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_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 benchmark_input_scf(request): pseudos = abidata.pseudos("14si.pspnc", "6c.pspnc", "3li.pspnc", "9f.pspnc", "12mg.pspnc", "8o.pspnc", "31ga.pspnc", "7n.pspnc") rest = MPRester() structure = rest.get_structure_by_material_id(request.param) try: return ebands_input(structure, pseudos, kppa=100, ecut=6).split_datasets()[0] except: #to deal with missing pseudos pytest.skip('Cannot create input for material {}.'.format(request.param))
def calculate_stability(self, d): m = MPRester(self.mapi_key) functional = d["pseudo_potential"]["functional"] syms = ["{} {}".format(functional, l) for l in d["pseudo_potential"]["labels"]] entry = ComputedEntry(Composition(d["unit_cell_formula"]), d["output"]["final_energy"], parameters={"hubbards": d["hubbards"], "potcar_symbols": syms}) data = m.get_stability([entry])[0] for k in ("e_above_hull", "decomposes_to"): d["analysis"][k] = data[k]
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 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"))
def setUp(self): self.rester = MPRester()
from pymatgen.ext.matproj import MPRester from pymatgen.analysis.interface_reactions import InterfacialReactivity from pymatgen.analysis.phase_diagram import PhaseDiagram, GrandPotentialPhaseDiagram from pymatgen import Composition, Element # %matplotlib inline # Initialize the REST API interface. You may need to put your own API key in as an arg. mpr = MPRester("NKnnBgWXU5o1S5ogiJGE") # Chemical formulae for two solid reactants. reactant1 = 'LiCoO2' reactant2 = 'Li3PS4' # Is the system open to an elemental reservoir? grand = True if grand: # Element in the elemental reservoir. open_el = 'Co' # Relative chemical potential vs. pure substance. Must be non-positive. relative_mu = -1 # Get the compositions of the reactants comp1 = Composition(reactant1) comp2 = Composition(reactant2) # Gather all elements involved in the chemical system. elements = [e.symbol for e in comp1.elements + comp2.elements] if grand: elements.append(open_el) elements = list(set(elements)) # Remove duplicates
to generate a new material POST https://www.materialsproject.org/rest/v2/query by {"criteria": "{'elements':{'$in':['Li', 'Na', 'K'], '$all': ['O']}, 'nelements':2}", "properties": "['formula', 'formation_energy_per_atom']"} GET or POST api_check https://www.materialsproject.org/rest/v1/api_check API 得到数据不但可以单独处理,还可以和我们自己计算出来的数据一起处理。 比如我们要计算 Li,Fe,O 三种元素的组成的相图, 我们可以用 mp_entries = m.get_entries_in_chemsys(["Li", "Fe", "O"])得到数据库里有的数据, 还可以通过pymatgen.apps.borg.hive 里的 VaspToComputedEntryDrone 功能把自己计算的结果和数据库种的数据一起分析: ''' import pymatgen as mg from pymatgen.ext.matproj import MPRester import configparser def getMyKey(): conf = configparser.ConfigParser() conf.read('config.ini') return conf.get('MP_INFO', 'MY_MP_KEY') MY_MP_KEY = getMyKey() with MPRester(MY_MP_KEY) as m: # structure = m.get_structure_by_material_id('C') # dos = m.get_dos_by_material_id('C') # bandStructure = m.get_bandstructure_by_material_id('C') # #把mp数据库里第1234号结构的,结构数据,dos和band数据得到了,分别保存在structure, dos, bandstructure这三个变量里 data = m.get_data('Fe2O3') # enengies = m.get_data('Fe2O3', 'energy') print(data[0])
class mp_query(object): def __init__(self, api_key): self.mpr = MPRester(api_key) def find_access_strings(self, search): data = self.mpr.get_data(search) material_ids = [datum['material_id'] for datum in data] return material_ids def mp_structure(self, material_id, standardize=True): struct = self.mpr.get_structure_by_material_id(material_id) if standardize: struct = SpacegroupAnalyzer(struct).get_conventional_standard_structure() return struct def make_structures(self, search): material_ids = self.find_access_strings(search) structures = [] for ID in material_ids: struct = self.mp_structure(ID) structures.append(struct) return structures def search_summary(self, search, print_energies=True, barplot=False, write_files=False, format='cif'): data = self.mpr.get_data(search) energies = [] for datum in data: f = datum['pretty_formula'] sn = str(datum['spacegroup']['number']) ss = datum['spacegroup']['symbol'] i = datum['material_id'] te = float(datum['energy']) ae = float(datum['energy_per_atom']) struct = self.mp_structure(i, standardize=False) ase_atoms = AseAtomsAdaptor.get_atoms(struct) composition = ase_atoms.get_chemical_formula() if write_files: write(f + '_' + sn + '.' + format, ase_atoms, format=format) energies.append((f, sn, ss, te, ae, composition)) energies.sort(key = lambda x: x[4]) if print_energies: print('formula spacegroup_number spacegroup_symbol total_energy energy_per_atom composition') for l in energies: print('{:7} {:<17} {:<17} {:<12.5f} {:<15f} {:<11}'.format(*l)) if barplot: energies = np.asarray(energies) epa = np.array(map(float, energies[:,4])) epa -= min(epa) xticks = [i + '_' + j for i,j in energies[:,0:2]] ind = np.arange(len(energies)) fig = plt.figure() plt.ylabel('Relative energy per atom / eV') plt.xlabel('Material') plt.xticks(ind, xticks, rotation=90) fig.set_size_inches(6.5,3) plt.savefig(search + '.tiff', dpi=300, bbox_inches='tight')
from pymatgen.core.periodic_table import Element from pymatgen.ext.matproj import MPRester from pymatgen.analysis.phase_diagram import PhaseDiagram,PDPlotter a = MPRester("Your API Key") #generate on Dashboard of MaterialProject entries = a.get_entries_in_chemsys(['Ca', 'C','O']) #generate a PhaseDiagram object pd = PhaseDiagram(entries) plotter = PDPlotter(pd) plotter.show() #show data using the pd, a PhaseDiagram object #all_entries(type: list): #people who use it can query all information of the phase construction, #which means they will get information about elements, #components made by those elements. Taking an example of Li-Fe-O system pd.all_entries #elements(type:list): generate a list of elements which using in phase diagram calculation. #Notes that elements has Element type requiring Element type from pymatgen.core.periodic_table class pd.elements #qhull_data(type: numpy.array): matrix contains composition data and energy data pd.qhull_data #Simplexes: The list of stable compositional coordinates in the phase diagram, #which we can use to draw a phase diagram.
def compute_environments(chemenv_configuration): string_sources = { 'cif': { 'string': 'a Cif file', 'regexp': r'.*\.cif$' }, 'mp': { 'string': 'the Materials Project database', 'regexp': r'mp-[0-9]+$' } } questions = {'c': 'cif'} questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[ chemenv_configuration.package_options['default_strategy']['strategy']] # TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options( chemenv_configuration.package_options['default_strategy'] ['strategy_options']) max_dist_factor = chemenv_configuration.package_options[ 'default_max_distance_factor'] firsttime = True while True: if len(questions) > 1: found = False print( 'Enter the source from which the structure is coming or <q> to quit :' ) for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format( key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input( 'Enter materials project id (e.g. "mp-1902") : ') a = MPRester() structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format( structure.composition.reduced_formula)) se = lgf.compute_structure_environments( maximum_distance_factor=max_dist_factor) print('Computing environments finished') while True: test = input( 'See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments( site) else: ces = strategy.get_site_coordination_environments_fractions( site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species # ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) csm = ce[1]['other_symmetry_measures'][ 'csm_wcs_ctwcc'] mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format( cg.name, cg.mp_symbol, 100.0 * ce[2], csm) if test in [ 'd', 'g' ] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][ thecg. coordination_number][0].minimum_geometries() for mingeom in mingeoms: csm = mingeom[1]['other_symmetry_measures'][ 'csm_wcs_ctwcc'] mystring += '{} : {:.2f} '.format( mingeom[0], csm) print(mystring) if test == 'g': while True: test = input( 'Enter index of site(s) (e.g. 0 1 2, separated by spaces) for which you want to see the grid ' 'of parameters : ') try: indices = [int(x) for x in test.split()] print(str(indices)) for isite in indices: if isite < 0: raise IndexError se.plot_environments( isite, additional_condition=se.AC.ONLY_ACB) break except ValueError: print('This is not a valid site') except IndexError: print('This site is out of the site range') if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input( 'View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ' ) if test in ['y', 'm']: if test == 'm': mydeltas = [] while True: try: test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append( np.array( [1.0 * i0, 1.0 * i1, 1.0 * i2], np.float)) break except (ValueError, IndexError): print('Not a valid multiplicity') else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site.species, site.frac_coords + mydelta, site.lattice, properties=site.properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.allcg.get_geometry_from_mp_symbol( ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
# import for this example from pymatgen.core.structure import Structure from pymatgen.core.lattice import Lattice # create Dash app as normal app = dash.Dash() # create the Structure object structure = Structure(Lattice.cubic(4.2), ["Na", "K"], [[0, 0, 0], [0.5, 0.5, 0.5]]) from pymatgen.ext.matproj import MPRester # create an input structure as an example structure_component = ctc.StructureMoleculeComponent( MPRester().get_structure_by_material_id("mp-804"), id="structure_in") # and a way to view the transformed structure structure_component_transformed = ctc.StructureMoleculeComponent( MPRester().get_structure_by_material_id("mp-804"), id="structure_out") # and the transformation component itself transformation_component = ctc.AllTransformationsComponent( input_structure_component=structure_component, ) # example layout to demonstrate capabilities of component my_layout = html.Div([ html.H1("TransformationComponent Example"), html.H2("Standard Layout"), transformation_component.layout(), html.H3("Example Input Structure"), structure_component.layout(size="500px"),
def setUp(self): self.rester = MPRester() warnings.simplefilter("ignore")
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://www.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, "Failed with property %s" % 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 = 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.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="mod_{}".format(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 = ["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) def test_pourbaix_heavy(self): entries = self.rester.get_pourbaix_entries(["Li", "Mg", "Sn", "Pd"]) pbx = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries(["Ba", "Ca", "V", "Cu", "F"]) pbx = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries(["Ba", "Ca", "V", "Cu", "F", "Fe"]) pbx = PourbaixDiagram(entries, nproc=4, filter_solids=False) entries = self.rester.get_pourbaix_entries(["Na", "Ca", "Nd", "Y", "Ho", "F"]) pbx = 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]))
for label in labels: cnts[label] += 1 print("labels:", cnts) 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)
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
MessageBody( dcc.Markdown( "The app is running in debug mode so will be slower than usual and error " "messages may appear." ) ), ], kind="warning", ), ], id="banner", ) api_offline, api_error = True, "Unknown error connecting to Materials Project API." try: with MPRester() as mpr: api_check = mpr._make_request("/api_check") if not api_check.get("api_key_valid", False): api_error = ( "Materials Project API key not supplied or not valid, " "please set PMG_MAPI_KEY in your environment." ) else: api_offline = False except Exception as exception: api_error = str(exception) if api_offline: banner = html.Div( [ html.Br(), MessageContainer(
def download_mp_crystals(self, elements, api_key=None, localpath=None, format='json', indent=4): """ Accesses Materials Project and downloads crystal structures containing the given elements. The structures are saved to the iprPy library as reference_crystal records. Parameters ---------- elements : list A list of element symbols. api_key : str, optional The user's Materials Project API key. If not given, will use "MAPI_KEY" environment variable """ assert format in ['json', 'xml'] # Function-specific imports import pymatgen as pmg from pymatgen.ext.matproj import MPRester # Define subset generator def subsets(fullset): """Yields element combination subsets""" for i, item in enumerate(fullset): yield [item] if len(fullset) > 1: for subset in subsets(fullset[i+1:]): yield [item] + subset # Load record style and set universal values style = 'reference_crystal' record = load_record(style) input_dict = {} input_dict['sourcename'] = "Materials Project" input_dict['sourcelink'] = "https://materialsproject.org/" input_dict['length_unit'] = "angstrom" # Set library subdirectory if localpath is None: localpath = self.localpath style_directory = Path(localpath, style) if not style_directory.is_dir(): style_directory.mkdir(parents=True) # Sort elements elements = aslist(elements) elements.sort() # Build list of downloaded entries have = [] for fname in style_directory.glob('mp-*.*'): have.append(fname.stem) # Open connection to Materials Project with MPRester(api_key) as m: # Loop over subsets of elements for subelements in subsets(elements): # Query MP for all entries corresponding to the elements entries = m.query({"elements": subelements}, ["material_id"]) # Add entries to the list if not there missing = [] for entry in entries: if entry['material_id'] not in have and entry['material_id'] not in missing: missing.append(entry['material_id']) # Download missing entries try: entries = m.query({"material_id": {"$in": missing}}, ['material_id', 'cif']) except: pass else: # Convert cif to model and save for entry in entries: entry_id = entry['material_id'] struct = pmg.Structure.from_str(entry['cif'], fmt='cif') struct = pmg.symmetry.analyzer.SpacegroupAnalyzer(struct).get_conventional_standard_structure() # Build record content input_dict['id'] = entry_id input_dict['ucell'] = am.load('pymatgen_Structure', struct).normalize() record.buildcontent(input_dict) # Save with open(Path(style_directory, f'{entry_id}.{format}'), 'w') as f: if format == 'json': record.content.json(fp=f, indent=indent) else: record.content.xml(fp=f, indent=indent) print('Added', entry_id)
print(MP_all) print(len(MP_all)) #test using small testing data #Data=pd.read_csv('test.csv',index_col=False, sep=',') f=open('CoulombResults_static.csv','w') f.write('Material ID,') for i in range(MaxAtoms): f.write('cm%s,' %str(i)) f.write('\n') EValFiles=np.atleast_1d(['CoulombResults_static.csv']) CMlists=[] with MPRester(API_Key) as mp:# Materials Project API imported for i in range(0,len(MP_all)): #MPName=Data['Materials ID'][i] MPName=MP_all[i] StructDat = mp.query(criteria={"task_id": MPName}, properties=['structure','nsites']) #print(StructDat) nAtoms=int(StructDat[0]['nsites']) #print(nAtoms) print(MPName) #redefine the size of CMat MaxAtoms=nAtoms+1 NuclearCharges=[] for qq in range(0,nAtoms): current=str(StructDat[0]['structure'].sites[qq]._species)
def get_bulk_gap_data(self): if not self.bulk_vr: path_to_bulk = self.defect_entry.parameters["bulk_path"] self.bulk_vr = Vasprun( os.path.join(path_to_bulk, "vasprun.xml")) bulk_sc_structure = self.bulk_vr.initial_structure mpid = self.defect_entry.parameters["mpid"] if not mpid: try: with MPRester() as mp: tmp_mplist = mp.get_entries_in_chemsys(list(bulk_sc_structure.symbol_set)) mplist = [ment.entry_id for ment in tmp_mplist if ment.composition.reduced_composition == \ bulk_sc_structure.composition.reduced_composition] except: raise ValueError("Error with querying MPRester for {}" "".format( bulk_sc_structure.composition.reduced_formula)) mpid_fit_list = [] for trial_mpid in mplist: with MPRester() as mp: mpstruct = mp.get_structure_by_material_id(trial_mpid) if StructureMatcher(primitive_cell=True, scale=False, attempt_supercell=True, allow_subset=False).fit(bulk_sc_structure, mpstruct): mpid_fit_list.append( trial_mpid) if len(mpid_fit_list) == 1: mpid = mpid_fit_list[0] print("Single mp-id found for bulk structure: {}.".format( mpid)) elif len(mpid_fit_list) > 1: num_mpid_list = [int(mp.split(""-"")[1]) for mp in mpid_fit_list] num_mpid_list.sort() mpid = "mp-"+str(num_mpid_list[0]) print("Multiple mp-ids found for bulk structure:{}\nWill use lowest number mpid " "for bulk band structure = {}.".format(str(mpid_fit_list), mpid)) else: print("Could not find bulk structure in MP database after tying the " "following list:\n{}".format( mplist)) mpid = None else: print("Manually fed mpid = {}".format( mpid)) vbm, cbm, bandgap = None, None, None gap_parameters = {} if mpid is not None: #TODO: NEED to be smarter about use of +U or HSE etc in MP gga band structure calculations... with MPRester() as mp: bs = mp.get_bandstructure_by_material_id( mpid) if bs: cbm = bs.get_cbm()["energy"] vbm = bs.get_vbm()["energy"] bandgap = bs.get_band_gap()["energy"] gap_parameters.update({"MP_gga_BScalc_data": bs.get_band_gap().copy()}) # contains gap kpt transition if vbm is None or bandgap is None or cbm is None: if mpid: print("WARNING: Mpid {} was provided, but no bandstructure entry currently exists for it. " "Reverting to use of bulk supercell calculation for band edge extrema.".format( mpid)) else: print( "WARNING: No mp-id provided, will fetch CBM/VBM details from the " "bulk calculation.") print("Note that it would be better to " "perform real band structure calculation...") gap_parameters.update( {"MP_gga_BScalc_data": None}) #to signal no MP BS is used bandgap, cbm, vbm, _ = self.bulk_vr.eigenvalue_band_properties gap_parameters.update( {"mpid": mpid, "cbm": cbm, "vbm": vbm, "gap": bandgap} ) self.defect_entry.parameters.update( gap_parameters) return
def get_mp_entries(self, full_sub_approach=False): """ This queries MP database for computed entries according to input bulk and sub elements of interest Args: mpid (str): Structure id of the system in the MP databse. mapi_key (str): Materials API key to access database (if not in ~/.pmgrc.yaml already) """ logger = logging.getLogger(__name__) if self.bulk_ce: self.bulk_species_symbol = [s.symbol for s in self.bulk_ce.composition.elements] self.redcomp = self.bulk_ce.composition.reduced_composition bce_override = True elif self.mpid: with MPRester(api_key=self.mapi_key) as mp: self.bulk_ce = mp.get_entry_by_material_id(self.mpid) self.bulk_species_symbol = [s.symbol for s in self.bulk_ce.composition.elements] self.redcomp = self.bulk_ce.composition.reduced_composition bce_override = False else: msg = "No bulk entry OR mpid supplied. " \ "Cannot compute atomic chempots without know the bulk entry of interest." logger.warning(msg) raise ValueError(msg) if full_sub_approach: #this can be time consuming if several sub species exist species_symbols = self.bulk_species_symbol[:] for sub_el in self.sub_species: species_symbols.append(sub_el) with MPRester(api_key=self.mapi_key) as mp: self.entries['bulk_derived'] = mp.get_entries_in_chemsys(species_symbols) self.entries['subs_set'] = {sub_el:[] for sub_el in self.sub_species} for entry in self.entries['bulk_derived']: for sub_el in self.sub_species: if sub_el in entry.composition: self.entries['subs_set'][sub_el].append(entry) else: #this is recommended approach for running sub species seperately (assumes subs are in dilute concentrations) with MPRester(api_key=self.mapi_key) as mp: self.entries['bulk_derived'] = mp.get_entries_in_chemsys(self.bulk_species_symbol) if self.mpid and bce_override: #overriding bulk_ce if mp-id is given. self.bulk_ce = mp.get_entry_by_material_id(self.mpid) if not self.entries: msg = "Could not fetch bulk entries for atomic chempots!" \ "MPRester query error." logger.warning(msg) raise ValueError(msg) # now compile substitution entries self.entries['subs_set'] = dict() bulk_entry_set = [entry.entry_id for entry in self.entries['bulk_derived']] for sub_el in self.sub_species: els = self.bulk_species_symbol + [sub_el] with MPRester(api_key=self.mapi_key) as mp: sub_entry_set = mp.get_entries_in_chemsys(els) if not sub_entry_set: msg = "Could not fetch sub entries for {} atomic chempots! " \ "Encountered MPRester query error".format(sub_el) logger.warning(msg) raise ValueError(msg) fin_sub_entry_set = [] for entry in sub_entry_set: if entry.entry_id not in bulk_entry_set: fin_sub_entry_set.append(entry) # All entries apart from the bulk entry set self.entries['subs_set'][sub_el] = fin_sub_entry_set return
#f=open(ff,'r') os.chdir(str(folder1)) #list_el=[] #lines=f.readlines() #content=(lines[3]).split(" ") #content=(lines[3]).split("' '|\n|\r\n") #for val in content: # if val != '' and val !='\n' and val !='\r\n': # list_el.append(val) # for i in range(0,len(list_el)): # if i!=0: # element_ff.append(list_el[i]) # print ff,' ',element_ff element_ff = ['C', 'H'] with MPRester(MAPI_KEY) as m: data = m.get_entries_in_chemsys( element_ff, inc_structure='final', property_data=[ "unit_cell_formula", "material_id", "icsd_id", "spacegroup", "energy_per_atom", "formation_energy_per_atom", "pretty_formula", "band_gap", "total_magnetization", "e_above_hull" ]) if (len(element_ff) > 1): try: entries = m.get_entries_in_chemsys(element_ff) pd = PhaseDiagram(entries) plotter = PDPlotter(pd, show_unstable=True) image = str(ff) + str("_DFT") + str(".jpg")
if not os.path.exists(directory): os.makedirs(directory) except OSError: print('Error: Creating directory. ' + directory) ############################################################################## def check_convergence(directory): v = Vasprun(directory + '/vasprun.xml') if not v.converged: print('Error: not converging !!') ############################################################################## MATERIAL_API_KEY = 'your_API_key' mpr = MPRester(MATERIAL_API_KEY) TM_list = [ 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Y', 'Zr', 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg' ] alkali_elements = [ 'Sr', 'Ba', 'K', 'Na', 'Li', 'Rb', 'Cs', 'Be', 'Mg', 'Ca', 'Ba', 'Si' ] ############################################################################## # Hubbard U choice U_dict = { 'Co': 3.32,
def get_mp_structures(elements, api_key=None, lib_directory=None): """ Accesses the Materials Project and downloads all structures for a list of elements as poscar files. Parameters ---------- elements : list A list of element symbols. api_key : str, optional The user's Materials Project API key. If not given, will use "MAPI_KEY" environment variable lib_directory : str Path to the lib_directory to save the poscar files to. Default uses the iprPy library/dft_structures directory. """ # Function-specific imports import pymatgen as pmg from pymatgen.ext.matproj import MPRester # Handle lib_directory if lib_directory is None: lib_directory = os.path.join(os.path.dirname(rootdir), 'library', 'ref') lib_directory = os.path.abspath(lib_directory) elements.sort() # Open connection to Materials Project with MPRester(api_key) as m: # Loop over subsets of elements for subelements in subsets(elements): # Set comp_directory elements_string = '-'.join(subelements) comp_directory = os.path.join(lib_directory, elements_string) if not os.path.isdir(comp_directory): os.makedirs(comp_directory) # Build list of downloaded entries have = [] for fname in glob.iglob(os.path.join(comp_directory, 'mp-*.poscar')): have.append(os.path.splitext(os.path.basename(fname))[0]) #print('Have', len(have), elements_string, 'records') # Query MP for all entries corresponding to the elements entries = m.query({"elements": subelements}, ["material_id"]) # Add entries to the list if not there missing = [] for entry in entries: if entry['material_id'] not in have and entry[ 'material_id'] not in missing: missing.append(entry['material_id']) #print('Missing', len(missing), elements_string, 'records') # Download missing entries entries = m.query({"material_id": { "$in": missing }}, ['material_id', 'cif']) # Convert cif to poscar and save for entry in entries: struct = pmg.Structure.from_str(entry['cif'], fmt='cif') struct = pmg.symmetry.analyzer.SpacegroupAnalyzer( struct).get_conventional_standard_structure() system = am.load('pymatgen_Structure', struct) system = system.normalize() structure_file = os.path.join(comp_directory, entry['material_id'] + '.poscar') system.dump('poscar', f=structure_file) print('Added', entry['material_id'])
from pymatgen.ext.matproj import MPRester from pymatgen.apps.borg.hive import VaspToComputedEntryDrone from pymatgen.apps.borg.queen import BorgQueen from pymatgen.entries.compatibility import MaterialsProjectCompatibility from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotte # Assimilate VASP calculations into ComputedEntry object. Let's assume that # the calculations are for a series of new LixSnySz phases that we want to # know the phase stability. drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, rootpath=".") entries = queen.get_data() # Obtain all existing Li-Sn-S phases using the Materials Project REST API with MPRester("Key") as m: mp_entries = m.get_entries_in_chemsys(["Li", "Sn", "S"]) # Combined entry from calculated run with Materials Project entries entries.extend(mp_entries) # Process entries using the MaterialsProjectCompatibility compat = MaterialsProjectCompatibility() entries = compat.process_entries(entries) # Generate and plot Li-Sn-S phase diagram pd = PhaseDiagram(entries) plotter = PDPlotter(pd, color='black', markerfacecolor='c', markersize=15,
MPINT_CONFIG = {} warnings.warn('mpint_config.yaml file not configured') #try: # MPINT_CONFIG = loadfn('~/.mpint_config.yaml') #except: # MPINT_CONFIG = {} # warnings.warn('mpint_config.yaml file not configured') # set environ variables for MAPI_KEY and VASP_PSP_DIR if MPINT_CONFIG.get('potentials', ''): os.environ['PMG_VASP_PSP_DIR'] = MPINT_CONFIG.get('potentials', '') MP_API = MPINT_CONFIG.get('mp_api', '') if MP_API: os.environ['MAPI_KEY'] = MP_API MPR = MPRester(MP_API) USERNAME = MPINT_CONFIG.get('username', None) VASP_STD_BIN = MPINT_CONFIG.get('normal_binary', None) VASP_TWOD_BIN = MPINT_CONFIG.get('twod_binary', None) VASP_NCL_BIN = MPINT_CONFIG.get('ncl_binary',None) VASP_SOL_BIN = MPINT_CONFIG.get('sol_binary',None) VASP_CUSTOM_BIN = MPINT_CONFIG.get('custom_binary',None) VDW_KERNEL = MPINT_CONFIG.get('vdw_kernel', None) VASP_PSP = MPINT_CONFIG.get('potentials', None) QUEUE_SYSTEM = MPINT_CONFIG.get('queue_system', None) QUEUE_TEMPLATE = MPINT_CONFIG.get('queue_template', None) if not QUEUE_SYSTEM: QUEUE_SYSTEM = 'slurm'
def __init__(self, api_key): self.mpr = MPRester(api_key)
s1 = pyxtal() try: s1.from_seed(pmg, tol=1e-3) except: print("wrong", pmg) if s1.group.number == 229 and len( s1.atom_sites) == 1 and s1.atom_sites[0].wp.multiplicity == 2: strs = '{:20s} {:3d} {:12s} {:6.2f}'.format( id, spg, composition.to_pretty_string(), comp) if comp > 0.45: strs += '+++++++' print(strs) print(s1.atom_sites) mpr = MPRester('fn8WQGgT9rvZAh6H') # insert your keys here #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",
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')
def _download(self): """ Downloads dataset provided it does not exist in self.path Returns: works (bool): true if download succeeded or file already exists """ if self.apikey is None: raise AtomsDataError( "Provide a valid API key in order to download the " "Materials Project data!") try: from pymatgen.ext.matproj import MPRester from pymatgen.core import Structure import pymatgen as pmg except: raise ImportError( "In order to download Materials Project data, you have to install " "pymatgen") # collect data atms_list = [] properties_list = [] key_value_pairs_list = [] with MPRester(self.apikey) as m: for N in range(1, 9): for nsites in range(0, 300, 30): ns = {"$lt": nsites + 31, "$gt": nsites} query = m.query( criteria={ "nelements": N, "is_compatible": True, "nsites": ns, }, properties=[ "structure", "energy_per_atom", "formation_energy_per_atom", "total_magnetization", "band_gap", "material_id", "warnings", "created_at", ], ) for k, q in enumerate(query): s = q["structure"] if type(s) is Structure: atms_list.append( Atoms( numbers=s.atomic_numbers, positions=s.cart_coords, cell=s.lattice.matrix, pbc=True, )) properties_list.append({ MaterialsProject.EPerAtom: q["energy_per_atom"], MaterialsProject.EformationPerAtom: q["formation_energy_per_atom"], MaterialsProject.TotalMagnetization: q["total_magnetization"], MaterialsProject.BandGap: q["band_gap"], }) key_value_pairs_list.append({ "material_id": q["material_id"], "created_at": q["created_at"], }) # write systems to database self.add_systems( atms_list, property_list=properties_list, key_value_pairs_list=key_value_pairs_list, ) self.set_metadata({})
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"])
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"])
def compute_environments(chemenv_configuration): string_sources = {'cif': {'string': 'a Cif file', 'regexp': r'.*\.cif$'}, 'mp': {'string': 'the Materials Project database', 'regexp': r'mp-[0-9]+$'}} questions = {'c': 'cif'} questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[chemenv_configuration.package_options['default_strategy']['strategy']] #TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options(chemenv_configuration.package_options['default_strategy']['strategy_options']) max_dist_factor = chemenv_configuration.package_options['default_max_distance_factor'] firsttime = True while True: if len(questions) > 1: found = False print('Enter the source from which the structure is coming or <q> to quit :') for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format(key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input('Enter materials project id (e.g. "mp-1902") : ') a = MPRester() structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format(structure.composition.reduced_formula)) se = lgf.compute_structure_environments(maximum_distance_factor=max_dist_factor) print('Computing environments finished') while True: test = input('See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments(site) else: ces = strategy.get_site_coordination_environments_fractions(site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species_and_occu #ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) csm = ce[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format(cg.name, cg.mp_symbol, 100.0*ce[2], csm) if test in ['d', 'g'] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][thecg.coordination_number][0].minimum_geometries() for mingeom in mingeoms: csm = mingeom[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += '{} : {:.2f} '.format(mingeom[0], csm) print(mystring) if test == 'g': while True: test = input('Enter index of site(s) (e.g. 0 1 2, separated by spaces) for which you want to see the grid of parameters : ') try: indices=[int(x) for x in test.split()] print(str(indices)) for isite in indices: if isite <0: raise IndexError se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) break except ValueError: print('This is not a valid site') except IndexError: print('This site is out of the site range') if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input('View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ') if test in ['y', 'm']: if test == 'm': mydeltas = [] while True: try: test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append(np.array([1.0*i0, 1.0*i1, 1.0*i2], np.float)) break except (ValueError,IndexError): print('Not a valid multiplicity') else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site._species, site._fcoords + mydelta, site._lattice, properties=site._properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.allcg.get_geometry_from_mp_symbol(ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
class MPResterTest(unittest.TestCase): _multiprocess_shared_ = True def setUp(self): self.rester = MPRester() warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") 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, 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 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"])
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)
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"])
#!/usr/bin/env python from pymatgen.ext.matproj import MPRester from pymatgen.io.vasp.inputs import Poscar import argparse as ap from pynter.__init__ import load_config API_KEY = load_config()['API_KEY'] with MPRester(API_KEY) as mpr: class MPDatabase: def __init__(self, mp_id=None): """ Class to retrieve data from Materials Project database Parameters ---------- mp_id : (str), optional Materials-ID. The default is None. """ self.mp_id = mp_id if mp_id else None self.api_key = API_KEY @property def mp_rester(self): return mpr def args(self): """
from pymatgen.ext.matproj import MPRester #REST API的适配器 from pymatgen import Composition #可以非常灵活的处理化学元素 from pymatgen.entries.computed_entries import ComputedEntry #从数据获取的数据生成的ComputedEntries列表,主要用于管理数据的 from pymatgen.core.units import FloatWithUnit #相关化学计算的单位转换功能 from pymatgen.analysis.reaction_calculator import ComputedReaction #通过化学反应物和化学反应生成物生成化学反应的类 #This initializes the REST adaptor. Put your own API key in if necessary. a = MPRester("S3lw1QomLO8bTiT7") #将API 秘钥输入适配器中,并且初始化适配器 #得到包含Ca.C O三种元素的所有化学式的所有条目 all_entries = a.get_entries_in_chemsys(['Ca', 'C', 'O']) #获取MP数据库中的所有ComputedEntries列表 #找出所有条目中能量最低的化学式信息 def get_most_stable_entry(formula): relevant_entries = [ entry for entry in all_entries if entry.composition.reduced_formula == Composition(formula).reduced_formula ] relevant_entries = sorted(relevant_entries, key=lambda e: e.energy_per_atom) return relevant_entries[0] CaO = get_most_stable_entry("CaO") CO2 = get_most_stable_entry("CO2") CaCO3 = get_most_stable_entry("CaCO3") reaction = ComputedReaction([CaO, CO2], [CaCO3]) #得到化学反应 energy = FloatWithUnit(reaction.calculated_reaction_energy,