Beispiel #1
0
def gen_element(ele_name, key):
    assert (type(ele_name) == str)
    mpr = MPRester(key)
    data = mpr.query({
        'elements': [ele_name],
        'nelements': 1
    },
                     properties=[
                         "task_id", "pretty_formula", 'formula',
                         "anonymous_formula", 'formation_energy_per_atom',
                         'energy_per_atom', 'structure'
                     ])
    for ii in data:
        work_path = make_path_mp(ii)
        os.makedirs(work_path, exist_ok=True)
        fposcar = os.path.join(work_path, 'POSCAR')
        fjson = os.path.join(work_path, 'data.json')
        ii['structure'].to('poscar', fposcar)
        ii['structure'].to('json', fjson)

    m = StructureMatcher()
    for ii in global_std_crystal.keys():
        ss = gen_ele_std(ele_name, ii)
        find = False
        for jj in data:
            if m.fit(ss, jj['structure']):
                find = True
                break
        if find:
            work_path = make_path_mp(jj)
            with open(os.path.join(work_path, 'std-crys'), 'w') as fp:
                fp.write(ii + '\n')
Beispiel #2
0
def gen_alloy(eles, key):

    mpr = MPRester(key)

    data = mpr.query({
        'elements': {
            '$all': eles
        },
        'nelements': len(eles)
    },
                     properties=[
                         "task_id", "pretty_formula", 'formula',
                         "anonymous_formula", 'formation_energy_per_atom',
                         'energy_per_atom', 'structure'
                     ])
    if len(data) == 0:
        return

    alloy_file = make_path_mp(data[0])
    os.makedirs(alloy_file, exist_ok=True)
    alloy_file = os.path.join(alloy_file, '..')
    alloy_file = os.path.join(alloy_file, 'alloy')
    with open(alloy_file, 'w') as fp:
        None

    for ii in data:
        work_path = make_path_mp(ii)
        os.makedirs(work_path, exist_ok=True)
        fposcar = os.path.join(work_path, 'POSCAR')
        fjson = os.path.join(work_path, 'data.json')
        ii['structure'].to('poscar', fposcar)
        ii['structure'].to('json', fjson)
Beispiel #3
0
def do_query(args):
    m = MPRester()
    try:
        criteria = json.loads(args.criteria)
    except json.decoder.JSONDecodeError:
        criteria = args.criteria
    if args.structure:
        count = 0
        for d in m.query(criteria, properties=["structure", "task_id"]):
            s = d["structure"]
            formula = re.sub(r"\s+", "", s.formula)
            if args.structure == "poscar":
                fname = "POSCAR.%s_%s" % (d["task_id"], formula)
            else:
                fname = "%s-%s.%s" % (d["task_id"], formula, args.structure)
            s.to(filename=fname)
            count += 1
        print("%d structures written!" % count)
    elif args.entries:
        entries = m.get_entries(criteria)
        dumpfn(entries, args.entries)
        print("%d entries written to %s!" % (len(entries), args.entries))
    else:
        props = ["e_above_hull", "spacegroup"]
        props += args.data
        entries = m.get_entries(criteria, property_data=props)
        t = []
        headers = ["mp-id", "Formula", "Spacegroup", "E/atom (eV)",
                   "E above hull (eV)"] + args.data
        for e in entries:
            row = [e.entry_id, e.composition.reduced_formula,
                   e.data["spacegroup"]["symbol"],
                   e.energy_per_atom, e.data["e_above_hull"]]
            row += [e.data[s] for s in args.data]

            t.append(row)

        t = sorted(t, key=lambda x: x[headers.index("E above hull (eV)")])
        print(tabulate(t, headers=headers, tablefmt="pipe", floatfmt=".3f"))
Beispiel #4
0
class MaterialsProject(BaseDataSource):
    """
    Query the Materials Project for Data.
    """
    def __init__(self, api_key: str = None):
        """
        Args:
            api_key (str or None): Materials Project API key.
        """
        self.mpr = MPRester(api_key=api_key)

    def get(self, criteria: Union[str, Dict],
            properties: List[str]) -> pd.DataFrame:  # type: ignore
        """
        Args:
            criteria (str or dict): Criteria for query
            properties (list): Properties to be queried.

        Returns:
            pandas DataFrame
        """
        data = self.mpr.query(criteria=criteria, properties=properties)
        return pd.DataFrame(data)
Beispiel #5
0
# create a ./data folder if it doesn't already exist
if not path.isdir(data_dir):
    os.mkdir(data_dir)

cif_folder = data_dir + prop + "_cifs/"
csv_path = data_dir + prop + ".csv"
api_key = sys.argv[1]

m = MPRester(api_key=api_key)

# skip radioactive elements and noble gases
elements = ["H", "Li", "Be", "B", "C", "N", "O", "F", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi"]

# query for property data of stable, ordered materials
data = m.query(criteria={"is_ordered":True, "e_above_hull":0}, properties=["full_formula",id,prop,"cif","elements"])

# convert to a dataframe
df = pd.DataFrame.from_records(data)

# drop out entries that have elements not in the list
inds_to_drop = []
for row in df.iterrows():
    if not set(row[1]["elements"]).intersection(set(elements))==set(row[1]["elements"]):
        inds_to_drop.append(row[0])

df = df.drop(inds_to_drop)

# and save as CSV (without cifs or element lists)
df = df.drop(["cif", "elements"], axis=1)
Beispiel #6
0
class MPResterTest(unittest.TestCase):

    def setUp(self):
        self.rester = MPRester()

    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_ids", "total_magnetization"]
        # unicode literals have been reintroduced in py>3.2
        expected_vals = [-191.33812137, -6.833504334642858, -2.551358929370749,
                         28, {k: v for k, v in {'P': 4, 'Fe': 4, 'O': 16, 'Li': 4}.items()},
                         "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0,
                         {k: v for k, v in {'Fe': 5.3, 'Li': 0.0, 'O': 0.0, 'P': 0.0}.items()}, True,
                         [u'mp-601412', u'mp-19017', u'mp-796535', u'mp-797820',
                          u'mp-540081', u'mp-797269'],
                         3.4662026991351147,
                         [159107, 154117, 160776, 99860, 181272, 166815,
                          260571, 92198, 165000, 155580, 38209, 161479, 153699,
                          260569, 260570, 200155, 260572, 181341, 181342,
                          72545, 56291, 97764, 162282, 155635],
                         16.0002716]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements',
                            'icsd_ids', 'task_ids']:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                self.assertEqual(set(expected_vals[i]),
                                 set(self.rester.get_data("mp-19017",
                                                          prop=prop)[0][prop]))
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data("mp-19017",
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

    def test_get_materials_id_from_task_id(self):
        self.assertEqual(self.rester.get_materials_id_from_task_id(
            "mp-540081"), "mp-19017")

    def test_get_materials_id_references(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_get_materials_id_references
        m = MPRester()
        data = m.get_materials_id_references('mp-123')
        self.assertTrue(len(data) > 1000)

    def test_find_structure(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_find_structure
        m = MPRester()
        ciffile = os.path.join(test_dir, 'Fe3O4.cif')
        data = m.find_structure(ciffile)
        self.assertTrue(len(data) > 1)
        s = CifParser(ciffile).get_structures()[0]
        data = m.find_structure(s)
        self.assertTrue(len(data) > 1)

    def test_get_entries_in_chemsys(self):
        syms = ["Li", "Fe", "O"]
        entries = self.rester.get_entries_in_chemsys(syms)
        elements = set([Element(sym) for sym in syms])
        for e in entries:
            self.assertIsInstance(e, ComputedEntry)
            self.assertTrue(set(e.composition.elements).issubset(elements))

    def test_get_structure_by_material_id(self):
        s1 = self.rester.get_structure_by_material_id("mp-1")
        self.assertEqual(s1.formula, "Cs1")

    def test_get_entry_by_material_id(self):
        e = self.rester.get_entry_by_material_id("mp-19017")
        self.assertIsInstance(e, ComputedEntry)
        self.assertTrue(e.composition.reduced_formula, "LiFePO4")

    def test_query(self):
        criteria = {'elements': {'$in': ['Li', 'Na', 'K'], '$all': ['O']}}
        props = ['pretty_formula', 'energy']
        data = self.rester.query(criteria=criteria, properties=props)
        self.assertTrue(len(data) > 6)
        data = self.rester.query(criteria="*2O", properties=props)
        self.assertGreaterEqual(len(data), 52)
        self.assertIn("Li2O", (d["pretty_formula"] for d in data))

    def test_get_exp_thermo_data(self):
        data = self.rester.get_exp_thermo_data("Fe2O3")
        self.assertTrue(len(data) > 0)
        for d in data:
            self.assertEqual(d.formula, "Fe2O3")

    def test_get_dos_by_id(self):
        dos = self.rester.get_dos_by_material_id("mp-2254")
        self.assertIsInstance(dos, CompleteDos)

    def test_get_bandstructure_by_material_id(self):
        bs = self.rester.get_bandstructure_by_material_id("mp-2254")
        self.assertIsInstance(bs, BandStructureSymmLine)

    def test_get_structures(self):
        structs = self.rester.get_structures("Mn3O4")
        self.assertTrue(len(structs) > 0)

    def test_get_entries(self):
        entries = self.rester.get_entries("TiO2")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.composition.reduced_formula, "TiO2")

        entries = self.rester.get_entries("TiO2", inc_structure="final")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.structure.composition.reduced_formula, "TiO2")

        # all_entries = self.rester.get_entries("Fe", compatible_only=False)
        # entries = self.rester.get_entries("Fe", compatible_only=True)
        # self.assertTrue(len(entries) < len(all_entries))

        entries = self.rester.get_entries("Fe", compatible_only=True,
                                          property_data=["cif"])
        self.assertIn("cif", entries[0].data)

        for e in self.rester.get_entries("CdO2", inc_structure=False):
            self.assertIsNotNone(e.data["oxide_type"])

    def test_get_exp_entry(self):
        entry = self.rester.get_exp_entry("Fe2O3")
        self.assertEqual(entry.energy, -825.5)

    def test_submit_query_delete_snl(self):
        s = Structure([[5, 0, 0], [0, 5, 0], [0, 0, 5]], ["Fe"], [[0, 0, 0]])
        # d = self.rester.submit_snl(
        #     [s, s], remarks=["unittest"],
        #     authors="Test User <*****@*****.**>")
        # self.assertEqual(len(d), 2)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 2)
        # snlids = [d["_id"] for d in data]
        # self.rester.delete_snl(snlids)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 0)

    def test_get_stability(self):
        entries = self.rester.get_entries_in_chemsys(["Fe", "O"])
        modified_entries = []
        for entry in entries:
            # Create modified entries with energies that are 0.01eV higher
            # than the corresponding entries.
            if entry.composition.reduced_formula == "Fe2O3":
                modified_entries.append(
                    ComputedEntry(entry.composition,
                                  entry.uncorrected_energy + 0.01,
                                  parameters=entry.parameters,
                                  entry_id="mod_{}".format(entry.entry_id)))
        rest_ehulls = self.rester.get_stability(modified_entries)
        all_entries = entries + modified_entries
        compat = MaterialsProjectCompatibility()
        all_entries = compat.process_entries(all_entries)
        pd = PhaseDiagram(all_entries)
        a = PDAnalyzer(pd)
        for e in all_entries:
            if str(e.entry_id).startswith("mod"):
                for d in rest_ehulls:
                    if d["entry_id"] == e.entry_id:
                        data = d
                        break
                self.assertAlmostEqual(a.get_e_above_hull(e),
                                       data["e_above_hull"])

    def test_get_reaction(self):
        rxn = self.rester.get_reaction(["Li", "O"], ["Li2O"])
        self.assertIn("Li2O", rxn["Experimental_references"])

    def test_get_substrates(self):
        substrate_data = self.rester.get_substrates('mp-123', 5, [1, 0, 0])
        substrates = [sub_dict['sub_id'] for sub_dict in substrate_data]
        self.assertIn("mp-2534", substrates)

    def test_parse_criteria(self):
        crit = MPRester.parse_criteria("mp-1234 Li-*")
        self.assertIn("Li-O", crit["$or"][1]["chemsys"]["$in"])
        self.assertIn({"task_id": "mp-1234"}, crit["$or"])

        crit = MPRester.parse_criteria("Li2*")
        self.assertIn("Li2O", crit["pretty_formula"]["$in"])
        self.assertIn("Li2I", crit["pretty_formula"]["$in"])
        self.assertIn("CsLi2", crit["pretty_formula"]["$in"])

        crit = MPRester.parse_criteria("Li-*-*")
        self.assertIn("Li-Re-Ru", crit["chemsys"]["$in"])
        self.assertNotIn("Li-Li", crit["chemsys"]["$in"])

        comps = MPRester.parse_criteria("**O3")["pretty_formula"]["$in"]
        for c in comps:
            self.assertEqual(len(Composition(c)), 3, "Failed in %s" % c)

        chemsys = MPRester.parse_criteria("{Fe,Mn}-O")["chemsys"]["$in"]
        self.assertEqual(len(chemsys), 2)
        comps = MPRester.parse_criteria("{Fe,Mn,Co}O")["pretty_formula"]["$in"]
        self.assertEqual(len(comps), 3, comps)

        #Let's test some invalid symbols

        self.assertRaises(ValueError, MPRester.parse_criteria, "li-fe")
        self.assertRaises(ValueError, MPRester.parse_criteria, "LO2")

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
Beispiel #7
0
class MPResterTest(unittest.TestCase):

    def setUp(self):
        self.rester = MPRester()

    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_ids", "total_magnetization"]
        # unicode literals have been reintroduced in py>3.2
        expected_vals = [-191.33812137, -6.833504334642858, -2.551358929370749,
                         28, {k: v for k, v in {'P': 4, 'Fe': 4, 'O': 16, 'Li': 4}.items()},
                         "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0,
                         {k: v for k, v in {'Fe': 5.3, 'Li': 0.0, 'O': 0.0, 'P': 0.0}.items()}, True,
                         [u'mp-601412', u'mp-19017', u'mp-796535', u'mp-797820',
                          u'mp-540081', u'mp-797269'],
                         3.4662026991351147,
                         [159107, 154117, 160776, 99860, 181272, 166815,
                          260571, 92198, 165000, 155580, 38209, 161479, 153699,
                          260569, 260570, 200155, 260572, 181341, 181342,
                          72545, 56291, 97764, 162282, 155635],
                         16.0002716]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements',
                            'icsd_ids', 'task_ids']:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                self.assertEqual(set(expected_vals[i]),
                                 set(self.rester.get_data("mp-19017",
                                                          prop=prop)[0][prop]))
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data("mp-19017",
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

    def test_get_materials_id_from_task_id(self):
        self.assertEqual(self.rester.get_materials_id_from_task_id(
            "mp-540081"), "mp-19017")

    def test_get_materials_id_references(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_get_materials_id_references
        m = MPRester()
        data = m.get_materials_id_references('mp-123')
        self.assertTrue(len(data) > 1000)

    def test_find_structure(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_find_structure
        m = MPRester()
        ciffile = os.path.join(test_dir, 'Fe3O4.cif')
        data = m.find_structure(ciffile)
        self.assertTrue(len(data) > 1)
        s = CifParser(ciffile).get_structures()[0]
        data = m.find_structure(s)
        self.assertTrue(len(data) > 1)

    def test_get_entries_in_chemsys(self):
        syms = ["Li", "Fe", "O"]
        entries = self.rester.get_entries_in_chemsys(syms)
        elements = set([Element(sym) for sym in syms])
        for e in entries:
            self.assertIsInstance(e, ComputedEntry)
            self.assertTrue(set(e.composition.elements).issubset(elements))

    def test_get_structure_by_material_id(self):
        s1 = self.rester.get_structure_by_material_id("mp-1")
        self.assertEqual(s1.formula, "Cs1")

    def test_get_entry_by_material_id(self):
        e = self.rester.get_entry_by_material_id("mp-19017")
        self.assertIsInstance(e, ComputedEntry)
        self.assertTrue(e.composition.reduced_formula, "LiFePO4")

    def test_query(self):
        criteria = {'elements': {'$in': ['Li', 'Na', 'K'], '$all': ['O']}}
        props = ['pretty_formula', 'energy']
        data = self.rester.query(criteria=criteria, properties=props)
        self.assertTrue(len(data) > 6)
        data = self.rester.query(criteria="*2O", properties=props)
        self.assertGreaterEqual(len(data), 52)
        self.assertIn("Li2O", (d["pretty_formula"] for d in data))

    def test_get_exp_thermo_data(self):
        data = self.rester.get_exp_thermo_data("Fe2O3")
        self.assertTrue(len(data) > 0)
        for d in data:
            self.assertEqual(d.formula, "Fe2O3")

    def test_get_dos_by_id(self):
        dos = self.rester.get_dos_by_material_id("mp-2254")
        self.assertIsInstance(dos, CompleteDos)

    def test_get_bandstructure_by_material_id(self):
        bs = self.rester.get_bandstructure_by_material_id("mp-2254")
        self.assertIsInstance(bs, BandStructureSymmLine)

    def test_get_structures(self):
        structs = self.rester.get_structures("Mn3O4")
        self.assertTrue(len(structs) > 0)

    def test_get_entries(self):
        entries = self.rester.get_entries("TiO2")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.composition.reduced_formula, "TiO2")

        entries = self.rester.get_entries("TiO2", inc_structure="final")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.structure.composition.reduced_formula, "TiO2")

        # all_entries = self.rester.get_entries("Fe", compatible_only=False)
        # entries = self.rester.get_entries("Fe", compatible_only=True)
        # self.assertTrue(len(entries) < len(all_entries))

        entries = self.rester.get_entries("Fe", compatible_only=True,
                                          property_data=["cif"])
        self.assertIn("cif", entries[0].data)

        for e in self.rester.get_entries("CdO2", inc_structure=False):
            self.assertIsNotNone(e.data["oxide_type"])

    def test_get_exp_entry(self):
        entry = self.rester.get_exp_entry("Fe2O3")
        self.assertEqual(entry.energy, -825.5)

    def test_submit_query_delete_snl(self):
        s = Structure([[5, 0, 0], [0, 5, 0], [0, 0, 5]], ["Fe"], [[0, 0, 0]])
        # d = self.rester.submit_snl(
        #     [s, s], remarks=["unittest"],
        #     authors="Test User <*****@*****.**>")
        # self.assertEqual(len(d), 2)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 2)
        # snlids = [d["_id"] for d in data]
        # self.rester.delete_snl(snlids)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 0)

    def test_get_stability(self):
        entries = self.rester.get_entries_in_chemsys(["Fe", "O"])
        modified_entries = []
        for entry in entries:
            # Create modified entries with energies that are 0.01eV higher
            # than the corresponding entries.
            if entry.composition.reduced_formula == "Fe2O3":
                modified_entries.append(
                    ComputedEntry(entry.composition,
                                  entry.uncorrected_energy + 0.01,
                                  parameters=entry.parameters,
                                  entry_id="mod_{}".format(entry.entry_id)))
        rest_ehulls = self.rester.get_stability(modified_entries)
        all_entries = entries + modified_entries
        compat = MaterialsProjectCompatibility()
        all_entries = compat.process_entries(all_entries)
        pd = PhaseDiagram(all_entries)
        for e in all_entries:
            if str(e.entry_id).startswith("mod"):
                for d in rest_ehulls:
                    if d["entry_id"] == e.entry_id:
                        data = d
                        break
                self.assertAlmostEqual(pd.get_e_above_hull(e),
                                       data["e_above_hull"])

    def test_get_reaction(self):
        rxn = self.rester.get_reaction(["Li", "O"], ["Li2O"])
        self.assertIn("Li2O", rxn["Experimental_references"])

    def test_get_substrates(self):
        substrate_data = self.rester.get_substrates('mp-123', 5, [1, 0, 0])
        substrates = [sub_dict['sub_id'] for sub_dict in substrate_data]
        self.assertIn("mp-2534", substrates)

    def test_parse_criteria(self):
        crit = MPRester.parse_criteria("mp-1234 Li-*")
        self.assertIn("Li-O", crit["$or"][1]["chemsys"]["$in"])
        self.assertIn({"task_id": "mp-1234"}, crit["$or"])

        crit = MPRester.parse_criteria("Li2*")
        self.assertIn("Li2O", crit["pretty_formula"]["$in"])
        self.assertIn("Li2I", crit["pretty_formula"]["$in"])
        self.assertIn("CsLi2", crit["pretty_formula"]["$in"])

        crit = MPRester.parse_criteria("Li-*-*")
        self.assertIn("Li-Re-Ru", crit["chemsys"]["$in"])
        self.assertNotIn("Li-Li", crit["chemsys"]["$in"])

        comps = MPRester.parse_criteria("**O3")["pretty_formula"]["$in"]
        for c in comps:
            self.assertEqual(len(Composition(c)), 3, "Failed in %s" % c)

        chemsys = MPRester.parse_criteria("{Fe,Mn}-O")["chemsys"]["$in"]
        self.assertEqual(len(chemsys), 2)
        comps = MPRester.parse_criteria("{Fe,Mn,Co}O")["pretty_formula"]["$in"]
        self.assertEqual(len(comps), 3, comps)

        #Let's test some invalid symbols

        self.assertRaises(ValueError, MPRester.parse_criteria, "li-fe")
        self.assertRaises(ValueError, MPRester.parse_criteria, "LO2")

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
Beispiel #8
0
    def from_pymatgen_structure(
        structure=None,
        formula=None,
        space_grp=None,
        MP_key=None,
        conventional_standard_structure=True,
    ):
        """
        Create a Crystal object from a pymatgen Structure object.
        If a Materials Project API key is installed, you may pass
        the Materials Project ID of a structure, which will be
        fetched through the MP API. For setup information see:
        https://pymatgen.org/usage.html#setting-the-pmg-mapi-key-in-the-config-file.
        Alternatively, Materials Porject API key can be pass as an argument through
        the function (MP_key). To get your API key, please visit Materials Project website
        and login/sign up using your email id. Once logged in, go to the dashboard
        to generate your own API key (https://materialsproject.org/dashboard).

        Note that pymatgen typically prefers to return primitive unit cells,
        which can be overridden by setting conventional_standard_structure=True.

        Args:
            structure:      (pymatgen Structure or str), if specified as a string, it will be considered
                            as a Materials Project ID of a structure, otherwise it will accept only
                            pymatgen Structure object. if None, MP database will be queried using the
                            specified formula and/or space groups for the available structure
            formula:        (str), pretty formula to search in the MP database, (note that the forumlas in MP
                            database are not always formatted in the conventional order. Please
                            visit Materials Project website for information (https://materialsproject.org/)
                            if None, structure argument must not be None
            space_grp:      (int) space group number of the forumula provided to query MP database. If None, MP will search
                            for all the available space groups for the formula provided and will consider the
                            one with lowest unit cell volume, only specify when using formula to search MP
                            database
            MP_key:         (str) Materials Project API key
            conventional_standard_structure: (bool) if True, conventional standard unit cell will be returned
                            instead of the primitive unit cell pymatgen returns

        """
        import pymatgen as mg
        from pymatgen.ext.matproj import MPRester

        if structure is not None:
            if isinstance(structure, str):
                mpr = MPRester(MP_key)
                structure = mpr.get_structure_by_material_id(structure)

            assert isinstance(structure, mg.core.Structure
                              ), "structure must be pymatgen Structure object"

            structure = (mg.symmetry.analyzer.SpacegroupAnalyzer(
                structure).get_conventional_standard_structure()
                         if conventional_standard_structure else structure)
        else:
            mpr = MPRester(MP_key)
            if formula is None:
                raise Exception(
                    "Atleast a formula needs to be provided to query from MP database!!"
                )
            query = mpr.query(
                criteria={"pretty_formula": formula},
                properties=["structure", "icsd_ids", "spacegroup"],
            )
            if space_grp:
                query = [
                    query[i] for i in range(len(query))
                    if mg.symmetry.analyzer.SpacegroupAnalyzer(
                        query[i]["structure"]).get_space_group_number() ==
                    space_grp
                ]
            selected = query[np.argmin([
                query[i]["structure"].lattice.volume for i in range(len(query))
            ])]
            structure = (mg.symmetry.analyzer.SpacegroupAnalyzer(
                selected["structure"]).get_conventional_standard_structure()
                         if conventional_standard_structure else
                         selected["structure"])

        positions = structure.frac_coords  #: fractional atomic coordinates

        cell = np.array([
            structure.lattice.a,
            structure.lattice.b,
            structure.lattice.c,
            structure.lattice.alpha,
            structure.lattice.beta,
            structure.lattice.gamma,
        ])

        numbers = np.array([s.species.elements[0].Z for s in structure])

        return Crystal(positions, numbers, cell)
Beispiel #9
0
def fetch_materials_data(root_dir):
    # properties of interest
    properties = [ 
        # ID
        "material_id",
        "icsd_id",
        "icsd_ids",
        # structure
        "cif",
        "spacegroup",
        "crystal_system",
        "volume",
        "nsites", 
        # composition
        "unit_cell_formula",
        "pretty_formula",
        "elements", 
        "nelements",
        # energy
        "energy", 
        "energy_per_atom", 
        "formation_energy_per_atom",
        "e_above_hull",
        # electronic property
        "band_gap",
        "is_hubbard",
        "hubbards",
        "is_compatible",
        # mechanical property
        "elasticity",
        "piezo",
        'diel',
        # other property
        "density", 
        "total_magnetization",
        # additional info
        "oxide_type",
        "warnings",
        "task_ids",
        "tags"
    ]

    # MaterialsProject API settings
    my_API_key = None # put your API key here
    if not my_API_key:
        print("please specify your Materials Project API key here")
        sys.exit()
    m = MPRester(api_key=my_API_key)

    # query all materials data
    query_all = m.query(criteria={}, properties=properties)
    MPdata_all = pd.DataFrame(entry.values() for entry in query_all)
    MPdata_all.columns = properties

    # write cif to file
    cif_dir = os.path.join(root_dir, "MP_cifs")
    if os.path.exists(cif_dir):
        _ = input("MPdata_all/MP_cifs dir already exists, press Enter to continue, Ctrl+C to terminate..")
    else:
        os.mkdir(cif_dir)
    for _, irow in MPdata_all[["material_id", "cif"]].iterrows():
        cif_file = os.path.join(cif_dir, irow["material_id"] + ".cif")
        with open(cif_file, 'w') as f:
            f.write(irow["cif"])
    MPdata_all = MPdata_all.drop(columns=["cif"])

    # materials with calculated band structures
    query_band = m.query(criteria={"has": "bandstructure"},
                         properties=["material_id"])
    band_filenames = [list(entry.values())[0] for entry in query_band]
    MPdata_all['has_band_structure'] = MPdata_all["material_id"].isin(band_filenames)
    
    # write properties to file
    out_file = os.path.join(root_dir, "MPdata_all.csv")
    MPdata_all.to_csv(out_file, sep=';', index=False, header=MPdata_all.columns, mode='w')
    row.append(atom_r**3*10**(-7))
    ElemData.append(row)
   

Database=[]
print("Element Data Collection Completion:--- %s seconds ---" % (time.time() - start_time))
   
f.write('Comp,MPID,target,AvgElectron,sTot,pTot,dTot,fTot,NAtom,AvgIonicRad,DevIonicRad,VolumeAverageMass,AverageMass,DevMass,RedMass,AvgENeg,DiffENeg,DevENeg,AvgDipole,DevDipole,DiffDipole,TotalVolume,totalAtoms,density,OmegaAvg,OmegaDev,OmegaMax,OmegaMin,eHull,formE,gap,symm,lattA,lattB,lattC,lattAlpha,lattBeta,lattGamma')
f.write('\n')

numberofanalyzed=0

for i in range(0,numMaterials):

    
    stabdata = m.query(criteria={'material_id':ID[i]}, properties=["pretty_formula","formation_energy_per_atom","band_gap","spacegroup.number",'volume',
    'structure','density','e_above_hull','nsites'])

    
    symm=SymmGroupFinder(stabdata[0]['spacegroup.number'])
    gap = stabdata[0]['band_gap']
    volume=stabdata[0]['volume']
    formE=stabdata[0]['formation_energy_per_atom']
    lattA=stabdata[0]['structure'].lattice.a
    lattB=stabdata[0]['structure'].lattice.b
    lattC=stabdata[0]['structure'].lattice.c
    lattAlpha=stabdata[0]['structure'].lattice.angles[0]
    lattBeta=stabdata[0]['structure'].lattice.angles[1]
    lattGamma=stabdata[0]['structure'].lattice.angles[2]
    density=stabdata[0]['density']
    eHull=stabdata[0]['e_above_hull']
    NAtom=stabdata[0]['nsites']
Beispiel #11
0
# import names
input_filename = input("\nInput filename (CSV file only): ")
names = data_handler.import_csv(input_filename)

# create a folder to store cifs
dir_name = input_filename.replace('.csv', '')
os.mkdir(dir_name)
print('\nDirectory "' + dir_name +
      '" is created. All CIF files will be stored in this folder. \n')

# loop through all names
entries = []
for name in tqdm(names):
    data_handler.try_url('https://www.materialsproject.org')
    results = m.query(name, properties=['material_id',
                                        'spacegroup.number'])  # query
    for result in results:
        material_id = result['material_id']
        sgn = result['spacegroup.number']
        if sgn != 1 and sgn != 2:  # exclude triclinics
            structure = m.get_structure_by_material_id(
                material_id, conventional_unit_cell=True)
            symmetrized_structure = SpacegroupAnalyzer(
                structure).get_symmetrized_structure()
            entry = [name, sgn, material_id]
            entries.append(entry)
            CifWriter(symmetrized_structure,
                      symprec=0.01).write_file(dir_name + '/' + name + '_' +
                                               str(sgn) + '_' + material_id +
                                               '.cif')
Beispiel #12
0
 def to_cif(self):
     m = MPRester("iEe4KC8U9QBczglh")
     structure = m.query(self.id, ['initial_structure'])  # 改变不同的晶体ID录入不同的数字
     f = structure[0]['initial_structure']
     f1 = str(f) + '\n'
     j_pv_lst = re.findall('abc\s\s\s:\s\s\s(.*?)\n', f1)[0]
     j1_pv_lst = j_pv_lst.split('   ')
     a = float(j1_pv_lst[0])
     b = float(j1_pv_lst[1])
     c = float(j1_pv_lst[2])
     par_lst_matrix = [[a, 0, 0], [0, b, 0], [0, 0, c]]
     print(par_lst_matrix)
     # 物质种类(比如:Lu2 Al4)
     y1 = re.findall('Full\sFormula\s(.*?)\n', f1)[0]
     # y1_lst = y1.lstrip('(').rstrip(')')
     material = re.findall('Full\sFormula\s(.*?)\n',
                           f1)[0].lstrip('(').rstrip(')')
     self.mat_name = material
     elements = material.split(' ')
     element_lst = []
     num_lst = []
     for element in elements:  # 这个循环之后,得到原子与对应的原子数两个列表
         letter_lst = list(element)
         num_lst.append(letter_lst[-1])
         letter_lst.pop(-1)
         element1 = ''.join(letter_lst)
         element_lst.append(element1)
     par_lst_species = []  # 用于Cifwrite参数(species)的
     for i in range(len(num_lst)):
         num = int(num_lst[i])
         for j in range(num):
             par_lst_species.append(element_lst[i])
     print(par_lst_species)
     # 每个原子的坐标
     ord_lst = []  # 最终Cifwriter所需要的coords参数
     ord_lst2 = []  # 储存的形式为
     for element in element_lst:
         ord_lst1 = re.findall(element + '\s\s\s\s(.*?)\n', f1)
         for ord in ord_lst1:
             ord1 = ord.split(' ')
             while '' in ord1:
                 ord1.remove('')
             ord_lst2.append(ord1)
     for ord in ord_lst2:
         ord1 = []
         for string in ord:
             num = float(string)
             ord1.append(num)
             if len(ord1) == 3:
                 ord2 = ord1
         ord_lst.append(ord2)
     par_lst_coords = ord_lst
     print(par_lst_coords)
     # 构建Structure类
     structure = Structure(par_lst_matrix, par_lst_species, par_lst_coords)
     slab = CifWriter(
         structure, write_magmoms=True
     )  # struct (Structure) – structure to write; symprec (float) – If not none, finds the symmetry of the structure and writes the cif with symmetry information. Passes symprec to the SpacegroupAnalyzer; write_magmoms (bool) – If True, will write magCIF file. Incompatible with symprec
     slab.write_file(
         r'C:\Users\wang1\Desktop\2D\download vasp\{}.cif'.format(
             self.mat_name))
    'W': 7.17
}
U_elements = list(U_dict.keys())

##############################################################################
entries = mpr.query(criteria={
    "elements": {
        "$all": ["O"],
        "$in": TM_list
    },
    "anonymous_formula": {
        "A": 1,
        "B": 1,
        "C": 3
    },
    "nelements": 3,
    "spacegroup.number": 221,
    "crystal_system": "cubic",
    "spacegroup.symbol": "Pm-3m"
},
                    properties=[
                        "materials_id", "pretty_formula",
                        "formation_energy_per_atom", "cif", "structure",
                        "band_gap", "input.incar", "magnetic_type",
                        "total_magnetization", "e_above_hull", "volume",
                        "theoretical"
                    ])

print("%d entries were found" % len(entries))

sorted_entries = sorted(entries, key=lambda e: e['e_above_hull'])
# test_entries = sorted_entries[:10]
Beispiel #14
0
#define your search criteria
criteria ={#"band_gap": {"$gt":0.1},
           "spacegroup.number": {"$gt": 75},
           "nelements": {"$in": [2, 3]},
           "nsites": {"$lt": 60},
          }

#choose the properties which you are interested:
properties = [
    "material_id",
    "band_gap",
    "e_above_hull",
    "structure",
    "spacegroup.number",
    "composition_reduced",
    #"cif",
]
entries = mpr.query(criteria=criteria, properties=properties)
print("=============================Initial:", len(entries))

for i, entry in enumerate(entries):
    pmg = entry['structure']
    eles = [ele.symbol for ele in pmg.composition.elements]
    for ele in eles:
        pmg0 = pmg.copy()
        todo = [e0 for e0 in eles if e0 != ele]
        pmg0.remove_species(todo)
        comp = pmg.composition.fractional_composition.get_atomic_fraction(ele)
        process(pmg0, entry['material_id'], entry['spacegroup.number'],
                pmg.composition, comp)

print("Loading Data ......")
dataset = np.load('data/crystal_structures.npz')
features = np.array(dataset['xrd'], np.float32)
property = sys.argv[1]
if property == "crystal_system":
    labels = np.array(dataset['crystal_system'], int)
elif property == "space_group":
    labels = np.array(dataset['space_group'], int) - 1  # 0-index
else:
    mps = np.array(dataset['mp'])
    m = MPRester("wdRVIWP0Sdc4Xp4pxQt")
    labels = []
    for mp in mps:
        val = m.query(criteria={"task_id": mp}, properties=[property])
        labels.append(val)
    labels = np.array(labels)

print(features.shape)
print(labels.shape, min(labels), max(labels), len(set(labels)))

K = max(labels) + 1

features = features / np.amax(features, axis=1)[:, None]
analyze(K)

features, labels = shuffle(features, labels, random_state=0)

print("Generating data_loader ......")
Beispiel #16
0
class MaterialsProjectImporter(DbImporter):
    """
    Database importer for the Materials Project.
    """

    _properties = 'structure'
    _supported_keywords = None

    def __init__(self, **kwargs):
        """
        Instantiate the MaterialsProjectImporter by setting up the Materials API (MAPI)
        connection details.
        """
        self.setup_db(**kwargs)

    def setup_db(self, **kwargs):
        """
        Setup the required parameters to the REST API
        """
        try:
            api_key = kwargs['api_key']
        except KeyError:
            try:
                api_key = os.environ['PMG_MAPI_KEY']
            except KeyError as exception:
                raise KeyError(
                    'API key not supplied and PMG_MAPI_KEY environment variable not set. Either pass it when '
                    'initializing the class, or set the environment variable PMG_MAPI_KEY to your API key.'
                ) from exception
            api_key = None

        self._api_key = api_key
        self._verify_api_key()
        self._mpr = MPRester(self._api_key)

    def _verify_api_key(self):
        """
        Verify the supplied API key by issuing a request to Materials Project.
        """
        response = requests.get(
            'https://www.materialsproject.org/rest/v1/api_check', headers={'X-API-KEY': self._api_key}
        )
        response_content = response.json()  # a dict
        if 'error' in response_content:
            raise RuntimeError(response_content['error'])
        if not response_content['valid_response']:
            raise RuntimeError('Materials Project did not give a valid response for the API key check.')
        if not response_content['api_key_valid']:
            raise RuntimeError('Your API key for Materials Project is not valid.')

    @property
    def api_key(self):
        """
        Return the API key configured for the importer
        """
        return self._api_key

    @property
    def properties(self):
        """
        Return the properties that will be queried
        """
        return self._properties

    def get_supported_keywords(self):
        """
        Returns the list of all supported query keywords

        :return: list of strings
        """
        return self._supported_keywords

    def query(self, **kwargs):
        """
        Query the database with a given dictionary of query parameters for a given properties

        :param query: a dictionary with the query parameters
        :param properties: the properties to query
        """
        try:
            query = kwargs['query']
        except AttributeError:
            raise AttributeError(
                'Make sure the supplied dictionary has `query` as a key. This '
                'should contain a dictionary with the right query needed.'
            )
        try:
            properties = kwargs['properties']
        except AttributeError:
            raise AttributeError('Make sure the supplied dictionary has `properties` as a key.')

        if not isinstance(query, dict):
            raise TypeError('The query argument should be a dictionary')

        if properties is None:
            properties = self._properties

        if properties != 'structure':
            raise ValueError(f'Unsupported properties: {properties}')

        results = []
        properties_list = ['material_id', 'cif']
        for entry in self._find(query, properties_list):
            results.append(entry)
        search_results = MaterialsProjectSearchResults(results, return_class=MaterialsProjectCifEntry)

        return search_results

    def _find(self, query, properties):
        """
        Query the database with a given dictionary of query parameters

        :param query: a dictionary with the query parameters
        """
        for entry in self._mpr.query(criteria=query, properties=properties):
            yield entry
Beispiel #17
0
def query_all_of_materials_project():
    """
    Query all of the materials project in single element queries. Combines all the
    queries and writes the output to a pickle file
    """

    #Initialize the API query object
    API_key = 'mhaSG6L5b4HOQv2A'
    mp_rest = MPRester(API_key)

    #properties useful for project
    useful_properties = [
        u'energy', u'band_gap', u'e_above_hull', u'elements',
        u'pretty_formula', u'formation_energy_per_atom', u'cif', u'density',
        u'material_id', u'nelements', u'energy_per_atom'
    ]
    #Other Possible Properties
    #Full description of each property at
    #https://materialsproject.org/docs/api#materials_.28calculated_materials_data.29
    # ,u'is_compatible'
    # ,u'elasticity'
    # ,u'unit_cell_formula'
    # ,u'oxide_type'
    # ,u'hubbards'
    # ,u'task_ids'
    # ,u'nsites'
    # ,u'icsd_id'
    # ,u'tags'
    # ,u'volume'
    # ,u'total_magnetization'
    # ,u'is_hubbard'
    # ,u'spacegroup'
    # ,u'full_formula'

    #Divide the elements into groups of 1 to make small queries so PMG doesn't
    #get mad
    num_eles = len(chemical_symbols)
    divided = num_eles
    criteria_list = [{
        'elements': {
            '$all':
            chemical_symbols[x * num_eles / divided:num_eles * (x + 1) /
                             divided]
        }
    } for x in range(divided)]

    #For each criteria query the materials project and append the output
    query_output = []
    for criteria in criteria_list:
        print 'Querying Elements in Criteria : {0}'.format(criteria)
        query_output += mp_rest.query(criteria, useful_properties)

    #Need to remove any duplicate jobs (i.e. jobs with same material_id)
    unique_query_output = []
    counted_mat_ids = []
    for row in query_output:
        if not row['material_id'] in counted_mat_ids:
            unique_query_output.append(row)
            counted_mat_ids.append(row['material_id'])

    #Write the output to a pickle file
    project_folder = os.environ['CS230_Project_Folder']
    with open(project_folder + '/data/raw_data/mat_proj_query.pickle',
              'w') as file_curr:
        file_curr.write(pickle.dumps(new_output))

    return unique_query_output
Beispiel #18
0
                    elif k==len(TempSegment)-1 and isfloat(TempSegment[k])==False:
                        SeparatedName.append(TempSegment[k])
                        SeparatedName.append(str(multiplier))
    return(SeparatedName)

#test.cv is the compound list

g=open('CompoundDescriptorsMP_exception.csv','w')
f=open('CompoundDescriptorsMP.csv','w')
ID=[]
target=[]

API_Key='pF2RrzEPyZmIsLST'
m=MPRester(API_Key)

MPID_DICT= m.query(criteria={}, properties=["task_id"])
numMaterials=len(MPID_DICT)
print("Number Of Materials Analyzed:---%s---" % (numMaterials))

'''
Compounds=[]
for i in range(0,len(ID)):
    stabdata = m.query(criteria={'material_id':ID[i]}, properties=["pretty_formula"])
    Compounds.append(stabdata[0]['pretty_formula'])
#print(Compounds)
'''
print("API established")
ElementList=np.genfromtxt('NameListFile.txt',dtype=None)
Elements=[]
for i in range(0,len(ElementList)):
    Elements.append(ElementList[i][1].decode("utf-8"))
Beispiel #19
0
class MPResterTest(unittest.TestCase):

    def setUp(self):
        self.rester = MPRester()
        warnings.simplefilter("ignore")

    def tearDown(self):
        warnings.resetwarnings()

    def test_get_all_materials_ids_doc(self):
        mids = self.rester.get_materials_ids("Al2O3")
        random.shuffle(mids)
        doc = self.rester.get_doc(mids.pop(0))
        self.assertEqual(doc["pretty_formula"], "Al2O3")

    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_ids", "total_magnetization"]
        # unicode literals have been reintroduced in py>3.2
        expected_vals = [-191.33812137, -6.833504334642858, -2.551358929370749,
                         28, {k: v for k, v in {'P': 4, 'Fe': 4, 'O': 16, 'Li': 4}.items()},
                         "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0,
                         {k: v for k, v in {'Fe': 5.3, 'Li': 0.0, 'O': 0.0, 'P': 0.0}.items()}, True,
                         [u'mp-601412', u'mp-19017', u'mp-796535', u'mp-797820',
                          u'mp-540081', u'mp-797269'],
                         3.4662026991351147,
                         [159107, 154117, 160776, 99860, 181272, 166815,
                          260571, 92198, 165000, 155580, 38209, 161479, 153699,
                          260569, 260570, 200155, 260572, 181341, 181342,
                          72545, 56291, 97764, 162282, 155635],
                         16.0002716]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements',
                            'icsd_ids', 'task_ids']:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                self.assertEqual(set(expected_vals[i]),
                                 set(self.rester.get_data("mp-19017",
                                                          prop=prop)[0][prop]))
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data("mp-19017",
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

    def test_get_materials_id_from_task_id(self):
        self.assertEqual(self.rester.get_materials_id_from_task_id(
            "mp-540081"), "mp-19017")

    def test_get_materials_id_references(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_get_materials_id_references
        m = MPRester()
        data = m.get_materials_id_references('mp-123')
        self.assertTrue(len(data) > 1000)

    def test_find_structure(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_find_structure
        m = MPRester()
        ciffile = os.path.join(test_dir, 'Fe3O4.cif')
        data = m.find_structure(ciffile)
        self.assertTrue(len(data) > 1)
        s = CifParser(ciffile).get_structures()[0]
        data = m.find_structure(s)
        self.assertTrue(len(data) > 1)

    def test_get_entries_in_chemsys(self):
        syms = ["Li", "Fe", "O"]
        entries = self.rester.get_entries_in_chemsys(syms)
        elements = set([Element(sym) for sym in syms])
        for e in entries:
            self.assertIsInstance(e, ComputedEntry)
            self.assertTrue(set(e.composition.elements).issubset(elements))

    def test_get_structure_by_material_id(self):
        s1 = self.rester.get_structure_by_material_id("mp-1")
        self.assertEqual(s1.formula, "Cs1")

    def test_get_entry_by_material_id(self):
        e = self.rester.get_entry_by_material_id("mp-19017")
        self.assertIsInstance(e, ComputedEntry)
        self.assertTrue(e.composition.reduced_formula, "LiFePO4")

    def test_query(self):
        criteria = {'elements': {'$in': ['Li', 'Na', 'K'], '$all': ['O']}}
        props = ['pretty_formula', 'energy']
        data = self.rester.query(criteria=criteria, properties=props)
        self.assertTrue(len(data) > 6)
        data = self.rester.query(criteria="*2O", properties=props)
        self.assertGreaterEqual(len(data), 52)
        self.assertIn("Li2O", (d["pretty_formula"] for d in data))

    def test_get_exp_thermo_data(self):
        data = self.rester.get_exp_thermo_data("Fe2O3")
        self.assertTrue(len(data) > 0)
        for d in data:
            self.assertEqual(d.formula, "Fe2O3")

    def test_get_dos_by_id(self):
        dos = self.rester.get_dos_by_material_id("mp-2254")
        self.assertIsInstance(dos, CompleteDos)

    def test_get_bandstructure_by_material_id(self):
        bs = self.rester.get_bandstructure_by_material_id("mp-2254")
        self.assertIsInstance(bs, BandStructureSymmLine)
        bs_unif = self.rester.get_bandstructure_by_material_id(
            "mp-2254", line_mode=False)
        self.assertIsInstance(bs_unif, BandStructure)
        self.assertNotIsInstance(bs_unif, BandStructureSymmLine)

    def test_get_phonon_data_by_material_id(self):
        bs = self.rester.get_phonon_bandstructure_by_material_id("mp-661")
        self.assertIsInstance(bs, PhononBandStructureSymmLine)
        dos = self.rester.get_phonon_dos_by_material_id("mp-661")
        self.assertIsInstance(dos, CompletePhononDos)
        ddb_str = self.rester.get_phonon_ddb_by_material_id("mp-661")
        self.assertIsInstance(ddb_str, str)

    def test_get_structures(self):
        structs = self.rester.get_structures("Mn3O4")
        self.assertTrue(len(structs) > 0)

    def test_get_entries(self):
        entries = self.rester.get_entries("TiO2")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.composition.reduced_formula, "TiO2")

        entries = self.rester.get_entries("TiO2", inc_structure=True)
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.structure.composition.reduced_formula, "TiO2")

        # all_entries = self.rester.get_entries("Fe", compatible_only=False)
        # entries = self.rester.get_entries("Fe", compatible_only=True)
        # self.assertTrue(len(entries) < len(all_entries))

        entries = self.rester.get_entries("Fe", compatible_only=True,
                                          property_data=["cif"])
        self.assertIn("cif", entries[0].data)

        for e in self.rester.get_entries("CdO2", inc_structure=False):
            self.assertIsNotNone(e.data["oxide_type"])

        # test if it will retrieve the conventional unit cell of Ni
        entry = self.rester.get_entry_by_material_id(
            "mp-23", inc_structure=True, conventional_unit_cell=True)
        Ni = entry.structure
        self.assertEqual(Ni.lattice.a, Ni.lattice.b)
        self.assertEqual(Ni.lattice.a, Ni.lattice.c)
        self.assertEqual(Ni.lattice.alpha, 90)
        self.assertEqual(Ni.lattice.beta, 90)
        self.assertEqual(Ni.lattice.gamma, 90)

        # Ensure energy per atom is same
        primNi = self.rester.get_entry_by_material_id(
            "mp-23", inc_structure=True, conventional_unit_cell=False)
        self.assertEqual(primNi.energy_per_atom, entry.energy_per_atom)

        Ni = self.rester.get_structure_by_material_id(
            "mp-23", conventional_unit_cell=True)
        self.assertEqual(Ni.lattice.a, Ni.lattice.b)
        self.assertEqual(Ni.lattice.a, Ni.lattice.c)
        self.assertEqual(Ni.lattice.alpha, 90)
        self.assertEqual(Ni.lattice.beta, 90)
        self.assertEqual(Ni.lattice.gamma, 90)

        # Test case where convs are different from initial and final
        th = self.rester.get_structure_by_material_id(
            "mp-37", conventional_unit_cell=True)
        th_entry = self.rester.get_entry_by_material_id(
            "mp-37", inc_structure=True, conventional_unit_cell=True)
        th_entry_initial = self.rester.get_entry_by_material_id(
            "mp-37", inc_structure="initial", conventional_unit_cell=True)
        self.assertEqual(th, th_entry.structure)
        self.assertEqual(len(th_entry.structure), 4)
        self.assertEqual(len(th_entry_initial.structure), 2)


    def test_get_pourbaix_entries(self):
        pbx_entries = self.rester.get_pourbaix_entries(["Fe"])
        for pbx_entry in pbx_entries:
            self.assertTrue(isinstance(pbx_entry, PourbaixEntry))
        # Ensure entries are pourbaix compatible
        pbx = PourbaixDiagram(pbx_entries)

        # Try binary system
        pbx_entries = self.rester.get_pourbaix_entries(["Fe", "Cr"])
        pbx = PourbaixDiagram(pbx_entries)

        # Test Zn-S, which has Na in reference solids
        pbx_entries = self.rester.get_pourbaix_entries(["Zn", "S"])

    def test_get_exp_entry(self):
        entry = self.rester.get_exp_entry("Fe2O3")
        self.assertEqual(entry.energy, -825.5)

    def test_submit_query_delete_snl(self):
        s = Structure([[5, 0, 0], [0, 5, 0], [0, 0, 5]], ["Fe"], [[0, 0, 0]])
        # d = self.rester.submit_snl(
        #     [s, s], remarks=["unittest"],
        #     authors="Test User <*****@*****.**>")
        # self.assertEqual(len(d), 2)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 2)
        # snlids = [d["_id"] for d in data]
        # self.rester.delete_snl(snlids)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 0)

    def test_get_stability(self):
        entries = self.rester.get_entries_in_chemsys(["Fe", "O"])
        modified_entries = []
        for entry in entries:
            # Create modified entries with energies that are 0.01eV higher
            # than the corresponding entries.
            if entry.composition.reduced_formula == "Fe2O3":
                modified_entries.append(
                    ComputedEntry(entry.composition,
                                  entry.uncorrected_energy + 0.01,
                                  parameters=entry.parameters,
                                  entry_id="mod_{}".format(entry.entry_id)))
        rest_ehulls = self.rester.get_stability(modified_entries)
        all_entries = entries + modified_entries
        compat = MaterialsProjectCompatibility()
        all_entries = compat.process_entries(all_entries)
        pd = PhaseDiagram(all_entries)
        for e in all_entries:
            if str(e.entry_id).startswith("mod"):
                for d in rest_ehulls:
                    if d["entry_id"] == e.entry_id:
                        data = d
                        break
                self.assertAlmostEqual(pd.get_e_above_hull(e),
                                       data["e_above_hull"])

    def test_get_reaction(self):
        rxn = self.rester.get_reaction(["Li", "O"], ["Li2O"])
        self.assertIn("Li2O", rxn["Experimental_references"])

    def test_get_substrates(self):
        substrate_data = self.rester.get_substrates('mp-123', 5, [1, 0, 0])
        substrates = [sub_dict['sub_id'] for sub_dict in substrate_data]
        self.assertIn("mp-2534", substrates)

    def test_get_surface_data(self):
        data = self.rester.get_surface_data("mp-126") # Pt
        self.assertIn("surfaces", data)
        surfaces = data["surfaces"]
        self.assertTrue(len(surfaces) > 0)
        surface = surfaces.pop()
        self.assertIn("miller_index", surface)
        self.assertIn("surface_energy", surface)
        self.assertIn("is_reconstructed", surface)
        data_inc = self.rester.get_surface_data("mp-126", inc_structures=True)
        self.assertIn("structure", data_inc["surfaces"][0])

    def test_get_wulff_shape(self):
        ws = self.rester.get_wulff_shape("mp-126")
        self.assertTrue(isinstance(ws, WulffShape))

    def test_get_interface_reactions(self):
        kinks = self.rester.get_interface_reactions("LiCoO2", "Li3PS4")
        self.assertTrue(len(kinks) > 0)
        kink = kinks[0]
        self.assertIn("energy", kink)
        self.assertIn("ratio", kink)
        self.assertIn("rxn", kink)
        self.assertTrue(isinstance(kink['rxn'], Reaction))
        kinks_open_O = self.rester.get_interface_reactions(
            "LiCoO2", "Li3PS4", open_el="O", relative_mu=-1)
        self.assertTrue(len(kinks_open_O) > 0)
        with warnings.catch_warnings(record=True) as w:
            warnings.filterwarnings("always", message="The reactant.+")
            self.rester.get_interface_reactions("LiCoO2", "MnO3")
            self.assertTrue("The reactant" in str(w[-1].message))

    def test_parse_criteria(self):
        crit = MPRester.parse_criteria("mp-1234 Li-*")
        self.assertIn("Li-O", crit["$or"][1]["chemsys"]["$in"])
        self.assertIn({"task_id": "mp-1234"}, crit["$or"])

        crit = MPRester.parse_criteria("Li2*")
        self.assertIn("Li2O", crit["pretty_formula"]["$in"])
        self.assertIn("Li2I", crit["pretty_formula"]["$in"])
        self.assertIn("CsLi2", crit["pretty_formula"]["$in"])

        crit = MPRester.parse_criteria("Li-*-*")
        self.assertIn("Li-Re-Ru", crit["chemsys"]["$in"])
        self.assertNotIn("Li-Li", crit["chemsys"]["$in"])

        comps = MPRester.parse_criteria("**O3")["pretty_formula"]["$in"]
        for c in comps:
            self.assertEqual(len(Composition(c)), 3, "Failed in %s" % c)

        chemsys = MPRester.parse_criteria("{Fe,Mn}-O")["chemsys"]["$in"]
        self.assertEqual(len(chemsys), 2)
        comps = MPRester.parse_criteria("{Fe,Mn,Co}O")["pretty_formula"]["$in"]
        self.assertEqual(len(comps), 3, comps)

        #Let's test some invalid symbols

        self.assertRaises(ValueError, MPRester.parse_criteria, "li-fe")
        self.assertRaises(ValueError, MPRester.parse_criteria, "LO2")

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
from pymatgen.ext.matproj import MPRester
# Change "<APIKEY>" to the API key obtained from MP.
mpr = MPRester("<APIKEY>")
data = mpr.query(criteria={"pretty_formula": "Al2O3"},
                 properties=["final_energy", "band_gap"])
print(data)
import pandas as pd
df = pd.DataFrame(data)  # Convert to DataFrame
class MPResterTest(unittest.TestCase):

    def setUp(self):
        self.rester = MPRester()
        warnings.simplefilter("ignore")

    def tearDown(self):
        warnings.resetwarnings()

    def test_get_all_materials_ids_doc(self):
        mids = self.rester.get_materials_ids("Al2O3")
        random.shuffle(mids)
        doc = self.rester.get_doc(mids.pop(0))
        self.assertEqual(doc["pretty_formula"], "Al2O3")

    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_ids", "total_magnetization"]
        # unicode literals have been reintroduced in py>3.2

        expected_vals = [-191.3359011, -6.833425039285714, -2.5515769497278913,
                         28, {'P': 4, 'Fe': 4, 'O': 16, 'Li': 4},
                         "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0,
                         {'Fe': 5.3, 'Li': 0.0, 'O': 0.0, 'P': 0.0}, True,
                         {'mp-19017', 'mp-540081', 'mp-601412'},
                         3.464840709092822,
                         [159107, 154117, 160776, 99860, 181272, 166815,
                          260571, 92198, 165000, 155580, 38209, 161479, 153699,
                          260569, 260570, 200155, 260572, 181341, 181342,
                          72545, 56291, 97764, 162282, 155635],
                         15.9996841]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements',
                            'icsd_ids', 'task_ids']:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val, places=2)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                upstream_vals = set(
                    self.rester.get_data("mp-19017", prop=prop)[0][prop])
                self.assertLessEqual(set(expected_vals[i]), upstream_vals)
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data("mp-19017",
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

    def test_get_data(self):
        # Test getting supported properties
        self.assertNotEqual(self.rester.get_task_data("mp-30"), [])
        # Test aliasing
        data = self.rester.get_task_data("mp-30", "energy")
        self.assertAlmostEqual(data[0]["energy"], -4.09929227, places=2)

    def test_get_materials_id_from_task_id(self):
        self.assertEqual(self.rester.get_materials_id_from_task_id(
            "mp-540081"), "mp-19017")

    def test_get_materials_id_references(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_get_materials_id_references
        m = MPRester()
        data = m.get_materials_id_references('mp-123')
        self.assertTrue(len(data) > 1000)

    def test_find_structure(self):
        # nosetests pymatgen/matproj/tests/test_matproj.py:MPResterTest.test_find_structure
        m = MPRester()
        ciffile = os.path.join(test_dir, 'Fe3O4.cif')
        data = m.find_structure(ciffile)
        self.assertTrue(len(data) > 1)
        s = CifParser(ciffile).get_structures()[0]
        data = m.find_structure(s)
        self.assertTrue(len(data) > 1)

    def test_get_entries_in_chemsys(self):
        syms = ["Li", "Fe", "O"]
        entries = self.rester.get_entries_in_chemsys(syms)
        elements = set([Element(sym) for sym in syms])
        for e in entries:
            self.assertIsInstance(e, ComputedEntry)
            self.assertTrue(set(e.composition.elements).issubset(elements))

    def test_get_structure_by_material_id(self):
        s1 = self.rester.get_structure_by_material_id("mp-1")
        self.assertEqual(s1.formula, "Cs1")

    def test_get_entry_by_material_id(self):
        e = self.rester.get_entry_by_material_id("mp-19017")
        self.assertIsInstance(e, ComputedEntry)
        self.assertTrue(e.composition.reduced_formula, "LiFePO4")

    def test_query(self):
        criteria = {'elements': {'$in': ['Li', 'Na', 'K'], '$all': ['O']}}
        props = ['pretty_formula', 'energy']
        data = self.rester.query(criteria=criteria, properties=props)
        self.assertTrue(len(data) > 6)
        data = self.rester.query(criteria="*2O", properties=props)
        self.assertGreaterEqual(len(data), 52)
        self.assertIn("Li2O", (d["pretty_formula"] for d in data))

    def test_get_exp_thermo_data(self):
        data = self.rester.get_exp_thermo_data("Fe2O3")
        self.assertTrue(len(data) > 0)
        for d in data:
            self.assertEqual(d.formula, "Fe2O3")

    def test_get_dos_by_id(self):
        dos = self.rester.get_dos_by_material_id("mp-2254")
        self.assertIsInstance(dos, CompleteDos)

    def test_get_bandstructure_by_material_id(self):
        bs = self.rester.get_bandstructure_by_material_id("mp-2254")
        self.assertIsInstance(bs, BandStructureSymmLine)
        bs_unif = self.rester.get_bandstructure_by_material_id(
            "mp-2254", line_mode=False)
        self.assertIsInstance(bs_unif, BandStructure)
        self.assertNotIsInstance(bs_unif, BandStructureSymmLine)

    def test_get_phonon_data_by_material_id(self):
        bs = self.rester.get_phonon_bandstructure_by_material_id("mp-661")
        self.assertIsInstance(bs, PhononBandStructureSymmLine)
        dos = self.rester.get_phonon_dos_by_material_id("mp-661")
        self.assertIsInstance(dos, CompletePhononDos)
        ddb_str = self.rester.get_phonon_ddb_by_material_id("mp-661")
        self.assertIsInstance(ddb_str, str)

    def test_get_structures(self):
        structs = self.rester.get_structures("Mn3O4")
        self.assertTrue(len(structs) > 0)

    def test_get_entries(self):
        entries = self.rester.get_entries("TiO2")
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.composition.reduced_formula, "TiO2")

        entries = self.rester.get_entries("TiO2", inc_structure=True)
        self.assertTrue(len(entries) > 1)
        for e in entries:
            self.assertEqual(e.structure.composition.reduced_formula, "TiO2")

        # all_entries = self.rester.get_entries("Fe", compatible_only=False)
        # entries = self.rester.get_entries("Fe", compatible_only=True)
        # self.assertTrue(len(entries) < len(all_entries))

        entries = self.rester.get_entries("Fe", compatible_only=True,
                                          property_data=["cif"])
        self.assertIn("cif", entries[0].data)

        for e in self.rester.get_entries("CdO2", inc_structure=False):
            self.assertIsNotNone(e.data["oxide_type"])

        # test if it will retrieve the conventional unit cell of Ni
        entry = self.rester.get_entry_by_material_id(
            "mp-23", inc_structure=True, conventional_unit_cell=True)
        Ni = entry.structure
        self.assertEqual(Ni.lattice.a, Ni.lattice.b)
        self.assertEqual(Ni.lattice.a, Ni.lattice.c)
        self.assertEqual(Ni.lattice.alpha, 90)
        self.assertEqual(Ni.lattice.beta, 90)
        self.assertEqual(Ni.lattice.gamma, 90)

        # Ensure energy per atom is same
        primNi = self.rester.get_entry_by_material_id(
            "mp-23", inc_structure=True, conventional_unit_cell=False)
        self.assertEqual(primNi.energy_per_atom, entry.energy_per_atom)

        Ni = self.rester.get_structure_by_material_id(
            "mp-23", conventional_unit_cell=True)
        self.assertEqual(Ni.lattice.a, Ni.lattice.b)
        self.assertEqual(Ni.lattice.a, Ni.lattice.c)
        self.assertEqual(Ni.lattice.alpha, 90)
        self.assertEqual(Ni.lattice.beta, 90)
        self.assertEqual(Ni.lattice.gamma, 90)

        # Test case where convs are different from initial and final
        th = self.rester.get_structure_by_material_id(
            "mp-37", conventional_unit_cell=True)
        th_entry = self.rester.get_entry_by_material_id(
            "mp-37", inc_structure=True, conventional_unit_cell=True)
        th_entry_initial = self.rester.get_entry_by_material_id(
            "mp-37", inc_structure="initial", conventional_unit_cell=True)
        self.assertEqual(th, th_entry.structure)
        self.assertEqual(len(th_entry.structure), 4)
        self.assertEqual(len(th_entry_initial.structure), 2)

        # Test if the polymorphs of Fe are properly sorted
        # by e_above_hull when sort_by_e_above_hull=True
        Fe_entries = self.rester.get_entries("Fe", sort_by_e_above_hull=True)
        self.assertEqual(Fe_entries[0].data["e_above_hull"], 0)


    def test_get_pourbaix_entries(self):
        pbx_entries = self.rester.get_pourbaix_entries(["Fe"])
        for pbx_entry in pbx_entries:
            self.assertTrue(isinstance(pbx_entry, PourbaixEntry))
        # Ensure entries are pourbaix compatible
        pbx = PourbaixDiagram(pbx_entries)

        # Try binary system
        pbx_entries = self.rester.get_pourbaix_entries(["Fe", "Cr"])
        pbx = PourbaixDiagram(pbx_entries)

        # TODO: Shyue Ping: I do not understand this test. You seem to
        # be grabbing Zn-S system, but I don't see proper test for anything,
        # including Na ref. This test also takes a long time.

        # Test Zn-S, which has Na in reference solids
        # pbx_entries = self.rester.get_pourbaix_entries(["Zn", "S"])

    def test_get_exp_entry(self):
        entry = self.rester.get_exp_entry("Fe2O3")
        self.assertEqual(entry.energy, -825.5)

    def test_submit_query_delete_snl(self):
        s = Structure([[5, 0, 0], [0, 5, 0], [0, 0, 5]], ["Fe"], [[0, 0, 0]])
        # d = self.rester.submit_snl(
        #     [s, s], remarks=["unittest"],
        #     authors="Test User <*****@*****.**>")
        # self.assertEqual(len(d), 2)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 2)
        # snlids = [d["_id"] for d in data]
        # self.rester.delete_snl(snlids)
        # data = self.rester.query_snl({"about.remarks": "unittest"})
        # self.assertEqual(len(data), 0)

    def test_get_stability(self):
        entries = self.rester.get_entries_in_chemsys(["Fe", "O"])
        modified_entries = []
        for entry in entries:
            # Create modified entries with energies that are 0.01eV higher
            # than the corresponding entries.
            if entry.composition.reduced_formula == "Fe2O3":
                modified_entries.append(
                    ComputedEntry(entry.composition,
                                  entry.uncorrected_energy + 0.01,
                                  parameters=entry.parameters,
                                  entry_id="mod_{}".format(entry.entry_id)))
        rest_ehulls = self.rester.get_stability(modified_entries)
        all_entries = entries + modified_entries
        compat = MaterialsProjectCompatibility()
        all_entries = compat.process_entries(all_entries)
        pd = PhaseDiagram(all_entries)
        for e in all_entries:
            if str(e.entry_id).startswith("mod"):
                for d in rest_ehulls:
                    if d["entry_id"] == e.entry_id:
                        data = d
                        break
                self.assertAlmostEqual(pd.get_e_above_hull(e),
                                       data["e_above_hull"])

    def test_get_reaction(self):
        rxn = self.rester.get_reaction(["Li", "O"], ["Li2O"])
        self.assertIn("Li2O", rxn["Experimental_references"])

    def test_get_substrates(self):
        substrate_data = self.rester.get_substrates('mp-123', 5, [1, 0, 0])
        substrates = [sub_dict['sub_id'] for sub_dict in substrate_data]
        self.assertIn("mp-2534", substrates)

    def test_get_surface_data(self):
        data = self.rester.get_surface_data("mp-126") # Pt
        self.assertIn("surfaces", data)
        surfaces = data["surfaces"]
        self.assertTrue(len(surfaces) > 0)
        surface = surfaces.pop()
        self.assertIn("miller_index", surface)
        self.assertIn("surface_energy", surface)
        self.assertIn("is_reconstructed", surface)
        data_inc = self.rester.get_surface_data("mp-126", inc_structures=True)
        self.assertIn("structure", data_inc["surfaces"][0])

    def test_get_wulff_shape(self):
        ws = self.rester.get_wulff_shape("mp-126")
        self.assertTrue(isinstance(ws, WulffShape))

    def test_get_cohesive_energy(self):
        ecoh = self.rester.get_cohesive_energy("mp-13")
        self.assertTrue(ecoh, 5.04543279)

    def test_get_interface_reactions(self):
        kinks = self.rester.get_interface_reactions("LiCoO2", "Li3PS4")
        self.assertTrue(len(kinks) > 0)
        kink = kinks[0]
        self.assertIn("energy", kink)
        self.assertIn("ratio", kink)
        self.assertIn("rxn", kink)
        self.assertTrue(isinstance(kink['rxn'], Reaction))
        kinks_open_O = self.rester.get_interface_reactions(
            "LiCoO2", "Li3PS4", open_el="O", relative_mu=-1)
        self.assertTrue(len(kinks_open_O) > 0)
        with warnings.catch_warnings(record=True) as w:
            warnings.filterwarnings("always", message="The reactant.+")
            self.rester.get_interface_reactions("LiCoO2", "MnO9")
            self.assertTrue("The reactant" in str(w[-1].message))

    def test_parse_criteria(self):
        crit = MPRester.parse_criteria("mp-1234 Li-*")
        self.assertIn("Li-O", crit["$or"][1]["chemsys"]["$in"])
        self.assertIn({"task_id": "mp-1234"}, crit["$or"])

        crit = MPRester.parse_criteria("Li2*")
        self.assertIn("Li2O", crit["pretty_formula"]["$in"])
        self.assertIn("Li2I", crit["pretty_formula"]["$in"])
        self.assertIn("CsLi2", crit["pretty_formula"]["$in"])

        crit = MPRester.parse_criteria("Li-*-*")
        self.assertIn("Li-Re-Ru", crit["chemsys"]["$in"])
        self.assertNotIn("Li-Li", crit["chemsys"]["$in"])

        comps = MPRester.parse_criteria("**O3")["pretty_formula"]["$in"]
        for c in comps:
            self.assertEqual(len(Composition(c)), 3, "Failed in %s" % c)

        chemsys = MPRester.parse_criteria("{Fe,Mn}-O")["chemsys"]["$in"]
        self.assertEqual(len(chemsys), 2)
        comps = MPRester.parse_criteria("{Fe,Mn,Co}O")["pretty_formula"]["$in"]
        self.assertEqual(len(comps), 3, comps)

        #Let's test some invalid symbols

        self.assertRaises(ValueError, MPRester.parse_criteria, "li-fe")
        self.assertRaises(ValueError, MPRester.parse_criteria, "LO2")

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
Beispiel #22
0
# %%
perovskites["volume"] = perovskites.structure.apply(
    lambda struct: struct.volume)

perovskites.hist(column="volume", bins=50, log=True)

# %%
mpr = MPRester()
perovskites["likely_mp_ids"] = perovskites.structure.progress_apply(
    mpr.find_structure)

# %%
mp_ids = perovskites.likely_mp_ids.explode().value_counts().index.to_list()

es_above_hull = mpr.query({"material_id": {"$in": mp_ids}}, ["e_above_hull"])

# %%
ax = perovskites.likely_mp_ids.apply(len).value_counts().plot(kind="bar",
                                                              log=True)
annotate_bar_heights()
plt.savefig("likely_mp_ids_lens.pdf")

# %%
perovskites[["sg_symbol", "sg_number"]] = perovskites.progress_apply(
    lambda row: row.structure.get_space_group_info(),
    axis=1,
    result_type="expand")

perovskites["crystal_system"] = perovskites.structure.progress_apply(
    lambda struct: SpacegroupAnalyzer(struct).get_crystal_system())