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

            t.append(row)

        t = sorted(t, key=lambda x: x[headers.index("E above hull (eV)")])
        print(tabulate(t, headers=headers, tablefmt="pipe", floatfmt=".3f"))
Beispiel #7
0
 def setUp(self):
     self.rester = MPRester()
Beispiel #8
0
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
Beispiel #9
0
             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])
Beispiel #10
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')
Beispiel #11
0
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.
Beispiel #12
0
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)
Beispiel #17
0
class MaterialsProjectImporter(DbImporter):
    """
    Database importer for the Materials Project.
    """

    _properties = 'structure'
    _supported_keywords = None

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

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

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

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

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

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

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

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

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

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

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

        if properties is None:
            properties = self._properties

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

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

        return search_results

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

        :param query: a dictionary with the query parameters
        """
        for entry in self._mpr.query(criteria=query, properties=properties):
            yield entry
Beispiel #18
0
                    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(
Beispiel #19
0
    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)
Beispiel #20
0
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)
Beispiel #21
0
    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
Beispiel #22
0
    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
Beispiel #23
0
 def setUp(self):
     self.rester = MPRester()
Beispiel #24
0
        #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,
Beispiel #26
0
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'])
Beispiel #27
0
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,
Beispiel #28
0
   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'

Beispiel #29
0
 def __init__(self, api_key):
     self.mpr = MPRester(api_key)
Beispiel #30
0
    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",
Beispiel #31
0
def fetch_materials_data(root_dir):
    # properties of interest
    properties = [ 
        # ID
        "material_id",
        "icsd_id",
        "icsd_ids",
        # structure
        "cif",
        "spacegroup",
        "crystal_system",
        "volume",
        "nsites", 
        # composition
        "unit_cell_formula",
        "pretty_formula",
        "elements", 
        "nelements",
        # energy
        "energy", 
        "energy_per_atom", 
        "formation_energy_per_atom",
        "e_above_hull",
        # electronic property
        "band_gap",
        "is_hubbard",
        "hubbards",
        "is_compatible",
        # mechanical property
        "elasticity",
        "piezo",
        'diel',
        # other property
        "density", 
        "total_magnetization",
        # additional info
        "oxide_type",
        "warnings",
        "task_ids",
        "tags"
    ]

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

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

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

    # materials with calculated band structures
    query_band = m.query(criteria={"has": "bandstructure"},
                         properties=["material_id"])
    band_filenames = [list(entry.values())[0] for entry in query_band]
    MPdata_all['has_band_structure'] = MPdata_all["material_id"].isin(band_filenames)
    
    # write properties to file
    out_file = os.path.join(root_dir, "MPdata_all.csv")
    MPdata_all.to_csv(out_file, sep=';', index=False, header=MPdata_all.columns, mode='w')
Beispiel #32
0
    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({})
Beispiel #33
0
class MPResterTest(unittest.TestCase):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        #Let's test some invalid symbols

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

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

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

    def tearDown(self):
        warnings.resetwarnings()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        #Let's test some invalid symbols

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

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
Beispiel #35
0
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('')
Beispiel #36
0
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)
Beispiel #38
0
class MPResterTest(unittest.TestCase):
    def setUp(self):
        self.rester = MPRester()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        #Let's test some invalid symbols

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

        crit = MPRester.parse_criteria("POPO2")
        self.assertIn("P2O3", crit["pretty_formula"]["$in"])
#!/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,
 def setUp(self):
     self.rester = MPRester()
     warnings.simplefilter("ignore")
Beispiel #42
0
 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)