class MPResterTest(PymatgenTest): _multiprocess_shared_ = True def setUp(self): self.rester = MPRester() warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") self.rester.session.close() 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_xas_data(self): # Test getting XAS data data = self.rester.get_xas_data("mp-19017", "Li") self.assertEqual("mp-19017,Li", data["mid_and_el"]) self.assertAlmostEqual(data["spectrum"]["x"][0], 55.178, places=2) self.assertAlmostEqual(data["spectrum"]["y"][0], 0.0164634, places=2) 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", } mpid = "mp-1143" vals = requests.get( f"http://legacy.materialsproject.org/materials/{mpid}/json/") expected_vals = vals.json() for prop in props: if prop not in [ "hubbards", "unit_cell_formula", "elements", "icsd_ids", "task_ids", ]: val = self.rester.get_data(mpid, prop=prop)[0][prop] if prop in ["energy", "energy_per_atom"]: prop = "final_" + prop self.assertAlmostEqual(expected_vals[prop], val, 2, f"Failed with property {prop}") elif prop in ["elements", "icsd_ids", "task_ids"]: upstream_vals = set( self.rester.get_data(mpid, prop=prop)[0][prop]) self.assertLessEqual(set(expected_vals[prop]), upstream_vals) else: self.assertEqual( expected_vals[prop], self.rester.get_data(mpid, prop=prop)[0][prop], ) props = ["structure", "initial_structure", "final_structure", "entry"] for prop in props: obj = self.rester.get_data(mpid, prop=prop)[0][prop] if prop.endswith("structure"): self.assertIsInstance(obj, Structure) elif prop == "entry": obj = self.rester.get_data(mpid, 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 = self.TEST_FILES_DIR / "Fe3O4.cif" data = m.find_structure(str(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"] syms2 = "Li-Fe-O" entries = self.rester.get_entries_in_chemsys(syms) entries2 = self.rester.get_entries_in_chemsys(syms2) elements = {Element(sym) for sym in syms} for e in entries: self.assertIsInstance(e, ComputedEntry) self.assertTrue(set(e.composition.elements).issubset(elements)) e1 = {i.entry_id for i in entries} e2 = {i.entry_id for i in entries2} self.assertTrue(e1 == e2) stable_entries = self.rester.get_entries_in_chemsys( syms, additional_criteria={"e_above_hull": { "$lte": 0.001 }}) self.assertTrue(len(stable_entries) < len(entries)) def test_get_structure_by_material_id(self): s1 = self.rester.get_structure_by_material_id("mp-1") self.assertEqual(s1.formula, "Cs1") # requesting via task-id instead of mp-id self.assertWarns(Warning, self.rester.get_structure_by_material_id, "mp-698856") # requesting unknown mp-id self.assertRaises(MPRestError, self.rester.get_structure_by_material_id, "mp-does-not-exist") 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, chunk_size=0) self.assertTrue(len(data) > 6) data = self.rester.query(criteria="*2O", properties=props, chunk_size=0) self.assertGreaterEqual(len(data), 52) self.assertIn("Li2O", (d["pretty_formula"] for d in data)) def test_query_chunk_size(self): criteria = {"nelements": 2, "elements": "O"} props = ["pretty_formula"] data1 = self.rester.query(criteria=criteria, properties=props, chunk_size=0) data2 = self.rester.query(criteria=criteria, properties=props, chunk_size=500) self.assertEqual({d["pretty_formula"] for d in data1}, {d["pretty_formula"] for d in data2}) self.assertIn("Al2O3", {d["pretty_formula"] for d in data1}) 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): # test input chemsys as a list of elements pbx_entries = self.rester.get_pourbaix_entries(["Fe", "Cr"]) for pbx_entry in pbx_entries: self.assertTrue(isinstance(pbx_entry, PourbaixEntry)) # test input chemsys as a string pbx_entries = self.rester.get_pourbaix_entries("Fe-Cr") for pbx_entry in pbx_entries: self.assertTrue(isinstance(pbx_entry, PourbaixEntry)) # fe_two_plus = [e for e in pbx_entries if e.entry_id == "ion-0"][0] # self.assertAlmostEqual(fe_two_plus.energy, -1.12369, places=3) # # feo2 = [e for e in pbx_entries if e.entry_id == "mp-25332"][0] # self.assertAlmostEqual(feo2.energy, 3.56356, places=3) # # # Test S, which has Na in reference solids # pbx_entries = self.rester.get_pourbaix_entries(["S"]) # so4_two_minus = pbx_entries[9] # self.assertAlmostEqual(so4_two_minus.energy, 0.301511, places=3) # Ensure entries are Pourbaix compatible PourbaixDiagram(pbx_entries) 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=f"mod_{entry.entry_id}", )) rest_ehulls = self.rester.get_stability(modified_entries) all_entries = entries + modified_entries compat = MaterialsProject2020Compatibility() 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 one_surf = self.rester.get_surface_data("mp-129", miller_index=[-2, -3, 1]) self.assertAlmostEqual(one_surf["surface_energy"], 2.99156963, places=2) self.assertArrayAlmostEqual(one_surf["miller_index"], [3, 2, 1]) 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_gb_data(self): mo_gbs = self.rester.get_gb_data(chemsys="Mo") self.assertEqual(len(mo_gbs), 10) mo_gbs_s5 = self.rester.get_gb_data(pretty_formula="Mo", sigma=5) self.assertEqual(len(mo_gbs_s5), 3) mo_s3_112 = self.rester.get_gb_data( material_id="mp-129", sigma=3, gb_plane=[1, -1, -2], include_work_of_separation=True, ) self.assertEqual(len(mo_s3_112), 1) gb_f = mo_s3_112[0]["final_structure"] self.assertArrayAlmostEqual(gb_f.rotation_axis, [1, 1, 0]) self.assertAlmostEqual(gb_f.rotation_angle, 109.47122, places=4) self.assertAlmostEqual(mo_s3_112[0]["gb_energy"], 0.47965, places=2) self.assertAlmostEqual(mo_s3_112[0]["work_of_separation"], 6.318144, places=2) self.assertIn("Mo24", gb_f.formula) hcp_s7 = self.rester.get_gb_data(material_id="mp-87", gb_plane=[0, 0, 0, 1], include_work_of_separation=True) self.assertAlmostEqual(hcp_s7[0]["gb_energy"], 1.12, places=2) self.assertAlmostEqual(hcp_s7[0]["work_of_separation"], 2.47, places=2) 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_atomic", 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_download_info(self): material_ids = ["mvc-2970"] task_types = [TaskType.GGA_OPT, TaskType.GGAU_UNIFORM] file_patterns = ["vasprun*", "OUTCAR*"] meta, urls = self.rester.get_download_info(material_ids, task_types=task_types, file_patterns=file_patterns) self.assertDictEqual( dict(meta), { "mvc-2970": [{ "task_id": "mp-1738602", "task_type": "GGA+U NSCF Uniform" }], }, ) self.assertEqual( urls[0], "https://nomad-lab.eu/prod/rae/api/raw/query?file_pattern=vasprun*&file_pattern=OUTCAR*&external_id=mp" "-1738602", ) 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, f"Failed in {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"]) def test_include_user_agent(self): headers = self.rester.session.headers self.assertIn("user-agent", headers, msg="Include user-agent header by default") m = re.match( r"pymatgen/(\d+)\.(\d+)\.(\d+)\.?(\d+)? \(Python/(\d+)\.(\d)+\.(\d+) ([^\/]*)/([^\)]*)\)", headers["user-agent"], ) self.assertIsNotNone( m, msg=f"Unexpected user-agent value {headers['user-agent']}") self.rester = MPRester(include_user_agent=False) self.assertNotIn("user-agent", self.rester.session.headers, msg="user-agent header unwanted") def test_database_version(self): with MPRester(notify_db_version=True) as mpr: db_version = mpr.get_database_version() self.assertIsInstance(db_version, str) yaml = YAML() with open(MP_LOG_FILE) as f: d = yaml.load(f) self.assertEqual(d["MAPI_DB_VERSION"]["LAST_ACCESSED"], db_version) self.assertIsInstance(d["MAPI_DB_VERSION"]["LOG"][db_version], int) def test_pourbaix_heavy(self): entries = self.rester.get_pourbaix_entries(["Li", "Mg", "Sn", "Pd"]) _ = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries( ["Ba", "Ca", "V", "Cu", "F"]) _ = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries( ["Ba", "Ca", "V", "Cu", "F", "Fe"]) _ = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries( ["Na", "Ca", "Nd", "Y", "Ho", "F"]) _ = PourbaixDiagram(entries, nproc=4, filter_solids=False) def test_pourbaix_mpr_pipeline(self): data = self.rester.get_pourbaix_entries(["Zn"]) pbx = PourbaixDiagram(data, filter_solids=True, conc_dict={"Zn": 1e-8}) pbx.find_stable_entry(10, 0) data = self.rester.get_pourbaix_entries(["Ag", "Te"]) pbx = PourbaixDiagram(data, filter_solids=True, conc_dict={ "Ag": 1e-8, "Te": 1e-8 }) self.assertEqual(len(pbx.stable_entries), 29) test_entry = pbx.find_stable_entry(8, 2) self.assertEqual(sorted(test_entry.entry_id), ["ion-10", "mp-499"]) # Test against ion sets with multiple equivalent ions (Bi-V regression) entries = self.rester.get_pourbaix_entries(["Bi", "V"]) pbx = PourbaixDiagram(entries, filter_solids=True, conc_dict={ "Bi": 1e-8, "V": 1e-8 }) self.assertTrue( all([ "Bi" in entry.composition and "V" in entry.composition for entry in pbx.all_entries ]))
class MPResterTest(PymatgenTest): _multiprocess_shared_ = True def setUp(self): self.rester = MPRester() warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") self.rester.session.close() 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_xas_data(self): # Test getting XAS data data = self.rester.get_xas_data("mp-19017", "Li") self.assertEqual("mp-19017,Li", data['mid_and_el']) self.assertAlmostEqual(data['spectrum']['x'][0], 55.178, places=2) self.assertAlmostEqual(data['spectrum']['y'][0], 0.0164634, places=2) 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 = self.TEST_FILES_DIR / 'Fe3O4.cif' data = m.find_structure(str(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, chunk_size=0) self.assertTrue(len(data) > 6) data = self.rester.query( criteria="*2O", properties=props, chunk_size=0) self.assertGreaterEqual(len(data), 52) self.assertIn("Li2O", (d["pretty_formula"] for d in data)) def test_query_chunk_size(self): criteria = {"nelements": 2, "elements": "O"} props = ['pretty_formula'] data1 = self.rester.query( criteria=criteria, properties=props, chunk_size=0) data2 = self.rester.query( criteria=criteria, properties=props, chunk_size=500) self.assertEqual({d['pretty_formula'] for d in data1}, {d['pretty_formula'] for d in data2}) self.assertIn("Al2O3", {d['pretty_formula'] for d in data1}) 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", "Cr"]) 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 one_surf = self.rester.get_surface_data('mp-129', miller_index=[-2, -3, 1]) self.assertAlmostEqual(one_surf['surface_energy'], 2.99156963, places=2) self.assertArrayAlmostEqual(one_surf['miller_index'], [3, 2, 1]) 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_gb_data(self): mo_gbs = self.rester.get_gb_data(chemsys='Mo') self.assertEqual(len(mo_gbs), 10) mo_gbs_s5 = self.rester.get_gb_data(pretty_formula='Mo', sigma=5) self.assertEqual(len(mo_gbs_s5), 3) mo_s3_112 = self.rester.get_gb_data(material_id='mp-129', sigma=3, gb_plane=[1, -1, -2], include_work_of_separation=True) self.assertEqual(len(mo_s3_112), 1) gb_f = mo_s3_112[0]['final_structure'] self.assertArrayAlmostEqual(gb_f.rotation_axis, [1, 1, 0]) self.assertAlmostEqual(gb_f.rotation_angle, 109.47122, places=4) self.assertAlmostEqual(mo_s3_112[0]['gb_energy'], 0.47965, places=2) self.assertAlmostEqual(mo_s3_112[0]['work_of_separation'], 6.318144, places=2) self.assertIn("Mo24", gb_f.formula) hcp_s7 = self.rester.get_gb_data(material_id='mp-87', gb_plane=[0, 0, 0, 1], include_work_of_separation=True) self.assertAlmostEqual(hcp_s7[0]['gb_energy'], 1.12, places=2) self.assertAlmostEqual(hcp_s7[0]['work_of_separation'], 2.46, places=2) 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_atomic", 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"]) def test_include_user_agent(self): headers = self.rester.session.headers self.assertIn("user-agent", headers, msg="Include user-agent header by default") m = re.match( r"pymatgen/(\d+)\.(\d+)\.(\d+) \(Python/(\d+)\.(\d)+\.(\d+) ([^\/]*)/([^\)]*)\)", headers['user-agent']) self.assertIsNotNone(m, msg="Unexpected user-agent value {}".format(headers['user-agent'])) self.assertEqual(m.groups()[:3], tuple(pmg_version.split("."))) self.assertEqual( m.groups()[3:6], tuple(str(n) for n in (sys.version_info.major, sys.version_info.minor, sys.version_info.micro)) ) self.rester = MPRester(include_user_agent=False) self.assertNotIn("user-agent", self.rester.session.headers, msg="user-agent header unwanted")
class MPResterTest(PymatgenTest): _multiprocess_shared_ = True def setUp(self): self.rester = MPRester() warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") self.rester.session.close() 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_xas_data(self): # Test getting XAS data data = self.rester.get_xas_data("mp-19017", "Li") self.assertEqual("mp-19017,Li", data["mid_and_el"]) self.assertAlmostEqual(data["spectrum"]["x"][0], 55.178, places=2) self.assertAlmostEqual(data["spectrum"]["y"][0], 0.0164634, places=2) 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", ] expected_vals = [ -191.7661349, -6.848790532142857, -2.5571951564625857, 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.4708958823634912, [ 159107, 154117, 160776, 99860, 181272, 166815, 260571, 92198, 165000, 155580, 38209, 161479, 153699, 260569, 260570, 200155, 260572, 181341, 181342, 72545, 56291, 97764, 162282, 155635, ], 0, ] 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, 2, "Failed with property %s" % prop) 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") # 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 = self.TEST_FILES_DIR / "Fe3O4.cif" data = m.find_structure(str(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"] syms2 = "Li-Fe-O" entries = self.rester.get_entries_in_chemsys(syms) entries2 = self.rester.get_entries_in_chemsys(syms2) elements = set([Element(sym) for sym in syms]) for e in entries: self.assertIsInstance(e, ComputedEntry) self.assertTrue(set(e.composition.elements).issubset(elements)) e1 = set([i.entry_id for i in entries]) e2 = set([i.entry_id for i in entries2]) self.assertTrue(e1 == e2) def test_get_structure_by_material_id(self): s1 = self.rester.get_structure_by_material_id("mp-1") self.assertEqual(s1.formula, "Cs1") # requesting via task-id instead of mp-id self.assertWarns(Warning, self.rester.get_structure_by_material_id, "mp-698856") # requesting unknown mp-id self.assertRaises(MPRestError, self.rester.get_structure_by_material_id, "mp-does-not-exist") 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, chunk_size=0) self.assertTrue(len(data) > 6) data = self.rester.query(criteria="*2O", properties=props, chunk_size=0) self.assertGreaterEqual(len(data), 52) self.assertIn("Li2O", (d["pretty_formula"] for d in data)) def test_query_chunk_size(self): criteria = {"nelements": 2, "elements": "O"} props = ["pretty_formula"] data1 = self.rester.query(criteria=criteria, properties=props, chunk_size=0) data2 = self.rester.query(criteria=criteria, properties=props, chunk_size=500) self.assertEqual({d["pretty_formula"] for d in data1}, {d["pretty_formula"] for d in data2}) self.assertIn("Al2O3", {d["pretty_formula"] for d in data1}) 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): # test input chemsys as a list of elements pbx_entries = self.rester.get_pourbaix_entries(["Fe", "Cr"]) for pbx_entry in pbx_entries: self.assertTrue(isinstance(pbx_entry, PourbaixEntry)) # test input chemsys as a string pbx_entries = self.rester.get_pourbaix_entries("Fe-Cr") for pbx_entry in pbx_entries: self.assertTrue(isinstance(pbx_entry, PourbaixEntry)) fe_two_plus = [e for e in pbx_entries if e.entry_id == "ion-0"][0] self.assertAlmostEqual(fe_two_plus.energy, -1.6228450214319294, places=2) feo2 = [e for e in pbx_entries if e.entry_id == "mp-25332"][0] self.assertAlmostEqual(feo2.energy, 2.5523680849999995, places=2) # Test S, which has Na in reference solids pbx_entries = self.rester.get_pourbaix_entries(["S"]) so4_two_minus = pbx_entries[9] self.assertAlmostEqual(so4_two_minus.energy, 0.0644980568750011, places=2) # Ensure entries are pourbaix compatible PourbaixDiagram(pbx_entries) 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 one_surf = self.rester.get_surface_data("mp-129", miller_index=[-2, -3, 1]) self.assertAlmostEqual(one_surf["surface_energy"], 2.99156963, places=2) self.assertArrayAlmostEqual(one_surf["miller_index"], [3, 2, 1]) 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_gb_data(self): mo_gbs = self.rester.get_gb_data(chemsys="Mo") self.assertEqual(len(mo_gbs), 10) mo_gbs_s5 = self.rester.get_gb_data(pretty_formula="Mo", sigma=5) self.assertEqual(len(mo_gbs_s5), 3) mo_s3_112 = self.rester.get_gb_data( material_id="mp-129", sigma=3, gb_plane=[1, -1, -2], include_work_of_separation=True, ) self.assertEqual(len(mo_s3_112), 1) gb_f = mo_s3_112[0]["final_structure"] self.assertArrayAlmostEqual(gb_f.rotation_axis, [1, 1, 0]) self.assertAlmostEqual(gb_f.rotation_angle, 109.47122, places=4) self.assertAlmostEqual(mo_s3_112[0]["gb_energy"], 0.47965, places=2) self.assertAlmostEqual(mo_s3_112[0]["work_of_separation"], 6.318144, places=2) self.assertIn("Mo24", gb_f.formula) hcp_s7 = self.rester.get_gb_data(material_id="mp-87", gb_plane=[0, 0, 0, 1], include_work_of_separation=True) self.assertAlmostEqual(hcp_s7[0]["gb_energy"], 1.12, places=2) self.assertAlmostEqual(hcp_s7[0]["work_of_separation"], 2.47, places=2) 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_atomic", 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_download_info(self): material_ids = ["mp-32800", "mp-23494"] task_types = [TaskType.GGA_OPT, TaskType.GGA_UNIFORM] file_patterns = ["vasprun*", "OUTCAR*"] meta, urls = self.rester.get_download_info(material_ids, task_types=task_types, file_patterns=file_patterns) self.assertDictEqual( dict(meta), { "mp-23494": [{ "task_id": "mp-1752825", "task_type": "GGA NSCF Uniform" }], "mp-32800": [{ "task_id": "mp-739635", "task_type": "GGA NSCF Uniform" }], }, ) prefix = "http://labdev-nomad.esc.rzg.mpg.de/fairdi/nomad/mp/api/raw/query?" # previous test # ids = 'mp-23494,mp-688563,mp-32800,mp-746913' ids = "mp-1752825,mp-739635" self.assertEqual( urls[0], f"{prefix}file_pattern=vasprun*&file_pattern=OUTCAR*&external_id={ids}", ) 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"]) def test_include_user_agent(self): headers = self.rester.session.headers self.assertIn("user-agent", headers, msg="Include user-agent header by default") m = re.match( r"pymatgen/(\d+)\.(\d+)\.(\d+)\.?(\d+)? \(Python/(\d+)\.(\d)+\.(\d+) ([^\/]*)/([^\)]*)\)", headers["user-agent"], ) self.assertIsNotNone(m, msg="Unexpected user-agent value {}".format( headers["user-agent"])) self.rester = MPRester(include_user_agent=False) self.assertNotIn("user-agent", self.rester.session.headers, msg="user-agent header unwanted") def test_database_version(self): with MPRester(notify_db_version=True) as mpr: db_version = mpr.get_database_version() self.assertIsInstance(db_version, str) with open(SETTINGS_FILE, "rt") as f: d = yaml.safe_load(f) self.assertEqual(d["MAPI_DB_VERSION"]["LAST_ACCESSED"], db_version) self.assertIsInstance(d["MAPI_DB_VERSION"]["LOG"][db_version], int)