Files
gh-k-dense-ai-claude-scient…/skills/pymatgen/references/materials_project_api.md
2025-11-30 08:30:10 +08:00

12 KiB

Materials Project API Reference

This reference documents how to access and use the Materials Project database through pymatgen's API integration.

Overview

The Materials Project is a comprehensive database of computed materials properties, containing data on hundreds of thousands of inorganic crystals and molecules. The API provides programmatic access to this data through the MPRester client.

Installation and Setup

The Materials Project API client is now in a separate package:

pip install mp-api

Getting an API Key

  1. Visit https://next-gen.materialsproject.org/
  2. Create an account or log in
  3. Navigate to your dashboard/settings
  4. Generate an API key
  5. Store it as an environment variable:
export MP_API_KEY="your_api_key_here"

Or add to your shell configuration file (~/.bashrc, ~/.zshrc, etc.)

Basic Usage

Initialization

from mp_api.client import MPRester

# Using environment variable (recommended)
with MPRester() as mpr:
    # Perform queries
    pass

# Or explicitly pass API key
with MPRester("your_api_key_here") as mpr:
    # Perform queries
    pass

Important: Always use the with context manager to ensure sessions are properly closed.

Querying Materials Data

Search by Formula

with MPRester() as mpr:
    # Get all materials with formula
    materials = mpr.materials.summary.search(formula="Fe2O3")

    for mat in materials:
        print(f"Material ID: {mat.material_id}")
        print(f"Formula: {mat.formula_pretty}")
        print(f"Energy above hull: {mat.energy_above_hull} eV/atom")
        print(f"Band gap: {mat.band_gap} eV")
        print()

Search by Material ID

with MPRester() as mpr:
    # Get specific material
    material = mpr.materials.summary.search(material_ids=["mp-149"])[0]

    print(f"Formula: {material.formula_pretty}")
    print(f"Space group: {material.symmetry.symbol}")
    print(f"Density: {material.density} g/cm³")

Search by Chemical System

with MPRester() as mpr:
    # Get all materials in Fe-O system
    materials = mpr.materials.summary.search(chemsys="Fe-O")

    # Get materials in ternary system
    materials = mpr.materials.summary.search(chemsys="Li-Fe-O")

Search by Elements

with MPRester() as mpr:
    # Materials containing Fe and O
    materials = mpr.materials.summary.search(elements=["Fe", "O"])

    # Materials containing ONLY Fe and O (excluding others)
    materials = mpr.materials.summary.search(
        elements=["Fe", "O"],
        exclude_elements=True
    )

Getting Structures

Structure from Material ID

with MPRester() as mpr:
    # Get structure
    structure = mpr.get_structure_by_material_id("mp-149")

    # Get multiple structures
    structures = mpr.get_structures(["mp-149", "mp-510", "mp-19017"])

All Structures for a Formula

with MPRester() as mpr:
    # Get all Fe2O3 structures
    materials = mpr.materials.summary.search(formula="Fe2O3")

    for mat in materials:
        structure = mpr.get_structure_by_material_id(mat.material_id)
        print(f"{mat.material_id}: {structure.get_space_group_info()}")

Advanced Queries

Property Filtering

with MPRester() as mpr:
    # Materials with specific property ranges
    materials = mpr.materials.summary.search(
        chemsys="Li-Fe-O",
        energy_above_hull=(0, 0.05),  # Stable or near-stable
        band_gap=(1.0, 3.0),           # Semiconducting
    )

    # Magnetic materials
    materials = mpr.materials.summary.search(
        elements=["Fe"],
        is_magnetic=True
    )

    # Metals only
    materials = mpr.materials.summary.search(
        chemsys="Fe-Ni",
        is_metal=True
    )

Sorting and Limiting

with MPRester() as mpr:
    # Get most stable materials
    materials = mpr.materials.summary.search(
        chemsys="Li-Fe-O",
        sort_fields=["energy_above_hull"],
        num_chunks=1,
        chunk_size=10  # Limit to 10 results
    )

Electronic Structure Data

Band Structure

with MPRester() as mpr:
    # Get band structure
    bs = mpr.get_bandstructure_by_material_id("mp-149")

    # Analyze band structure
    if bs:
        print(f"Band gap: {bs.get_band_gap()}")
        print(f"Is metal: {bs.is_metal()}")
        print(f"Direct gap: {bs.get_band_gap()['direct']}")

        # Plot
        from pymatgen.electronic_structure.plotter import BSPlotter
        plotter = BSPlotter(bs)
        plotter.show()

Density of States

with MPRester() as mpr:
    # Get DOS
    dos = mpr.get_dos_by_material_id("mp-149")

    if dos:
        # Get band gap from DOS
        gap = dos.get_gap()
        print(f"Band gap from DOS: {gap} eV")

        # Plot DOS
        from pymatgen.electronic_structure.plotter import DosPlotter
        plotter = DosPlotter()
        plotter.add_dos("Total DOS", dos)
        plotter.show()

Fermi Surface

with MPRester() as mpr:
    # Get electronic structure data for Fermi surface
    bs = mpr.get_bandstructure_by_material_id("mp-149", line_mode=False)

Thermodynamic Data

Phase Diagram Construction

from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter

with MPRester() as mpr:
    # Get entries for phase diagram
    entries = mpr.get_entries_in_chemsys("Li-Fe-O")

    # Build phase diagram
    pd = PhaseDiagram(entries)

    # Plot
    plotter = PDPlotter(pd)
    plotter.show()

Pourbaix Diagram

from pymatgen.analysis.pourbaix_diagram import PourbaixDiagram, PourbaixPlotter

with MPRester() as mpr:
    # Get entries for Pourbaix diagram
    entries = mpr.get_pourbaix_entries(["Fe"])

    # Build Pourbaix diagram
    pb = PourbaixDiagram(entries)

    # Plot
    plotter = PourbaixPlotter(pb)
    plotter.show()

Formation Energy

with MPRester() as mpr:
    materials = mpr.materials.summary.search(material_ids=["mp-149"])

    for mat in materials:
        print(f"Formation energy: {mat.formation_energy_per_atom} eV/atom")
        print(f"Energy above hull: {mat.energy_above_hull} eV/atom")

Elasticity and Mechanical Properties

with MPRester() as mpr:
    # Search for materials with elastic data
    materials = mpr.materials.elasticity.search(
        chemsys="Fe-O",
        bulk_modulus_vrh=(100, 300)  # GPa
    )

    for mat in materials:
        print(f"{mat.material_id}: K = {mat.bulk_modulus_vrh} GPa")

Dielectric Properties

with MPRester() as mpr:
    # Get dielectric data
    materials = mpr.materials.dielectric.search(
        material_ids=["mp-149"]
    )

    for mat in materials:
        print(f"Dielectric constant: {mat.e_electronic}")
        print(f"Refractive index: {mat.n}")

Piezoelectric Properties

with MPRester() as mpr:
    # Get piezoelectric materials
    materials = mpr.materials.piezoelectric.search(
        piezoelectric_modulus=(1, 100)
    )

Surface Properties

with MPRester() as mpr:
    # Get surface data
    surfaces = mpr.materials.surface_properties.search(
        material_ids=["mp-149"]
    )

Molecule Data (For Molecular Materials)

with MPRester() as mpr:
    # Search molecules
    molecules = mpr.molecules.summary.search(
        formula="H2O"
    )

    for mol in molecules:
        print(f"Molecule ID: {mol.molecule_id}")
        print(f"Formula: {mol.formula_pretty}")

Bulk Data Download

Download All Data for Materials

with MPRester() as mpr:
    # Get comprehensive data
    materials = mpr.materials.summary.search(
        material_ids=["mp-149"],
        fields=[
            "material_id",
            "formula_pretty",
            "structure",
            "energy_above_hull",
            "band_gap",
            "density",
            "symmetry",
            "elasticity",
            "magnetic_ordering"
        ]
    )

Provenance and Calculation Details

with MPRester() as mpr:
    # Get calculation details
    materials = mpr.materials.summary.search(
        material_ids=["mp-149"],
        fields=["material_id", "origins"]
    )

    for mat in materials:
        print(f"Origins: {mat.origins}")

Working with Entries

ComputedEntry for Thermodynamic Analysis

with MPRester() as mpr:
    # Get entries (includes energy and composition)
    entries = mpr.get_entries_in_chemsys("Li-Fe-O")

    # Entries can be used directly in phase diagram analysis
    from pymatgen.analysis.phase_diagram import PhaseDiagram
    pd = PhaseDiagram(entries)

    # Check stability
    for entry in entries[:5]:
        e_above_hull = pd.get_e_above_hull(entry)
        print(f"{entry.composition.reduced_formula}: {e_above_hull:.3f} eV/atom")

Rate Limiting and Best Practices

Rate Limits

The Materials Project API has rate limits to ensure fair usage:

  • Be mindful of request frequency
  • Use batch queries when possible
  • Cache results locally for repeated analysis

Efficient Querying

# Bad: Multiple separate queries
with MPRester() as mpr:
    for mp_id in ["mp-149", "mp-510", "mp-19017"]:
        struct = mpr.get_structure_by_material_id(mp_id)  # 3 API calls

# Good: Single batch query
with MPRester() as mpr:
    structs = mpr.get_structures(["mp-149", "mp-510", "mp-19017"])  # 1 API call

Caching Results

import json

# Save results for later use
with MPRester() as mpr:
    materials = mpr.materials.summary.search(chemsys="Li-Fe-O")

    # Save to file
    with open("li_fe_o_materials.json", "w") as f:
        json.dump([mat.dict() for mat in materials], f)

# Load cached results
with open("li_fe_o_materials.json", "r") as f:
    cached_data = json.load(f)

Error Handling

from mp_api.client.core.client import MPRestError

try:
    with MPRester() as mpr:
        materials = mpr.materials.summary.search(material_ids=["invalid-id"])
except MPRestError as e:
    print(f"API Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Common Use Cases

Finding Stable Compounds

with MPRester() as mpr:
    # Get all stable compounds in a chemical system
    materials = mpr.materials.summary.search(
        chemsys="Li-Fe-O",
        energy_above_hull=(0, 0.001)  # Essentially on convex hull
    )

    print(f"Found {len(materials)} stable compounds")
    for mat in materials:
        print(f"  {mat.formula_pretty} ({mat.material_id})")

Battery Material Screening

with MPRester() as mpr:
    # Screen for potential cathode materials
    materials = mpr.materials.summary.search(
        elements=["Li"],  # Must contain Li
        energy_above_hull=(0, 0.05),  # Near stable
        band_gap=(0, 0.5),  # Metallic or small gap
    )

    print(f"Found {len(materials)} potential cathode materials")

Finding Materials with Specific Crystal Structure

with MPRester() as mpr:
    # Find materials with specific space group
    materials = mpr.materials.summary.search(
        chemsys="Fe-O",
        spacegroup_number=167  # R-3c (corundum structure)
    )

Integration with Other Pymatgen Features

All data retrieved from the Materials Project can be directly used with pymatgen's analysis tools:

with MPRester() as mpr:
    # Get structure
    struct = mpr.get_structure_by_material_id("mp-149")

    # Use with pymatgen analysis
    from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
    sga = SpacegroupAnalyzer(struct)

    # Generate surfaces
    from pymatgen.core.surface import SlabGenerator
    slabgen = SlabGenerator(struct, (1,0,0), 10, 10)
    slabs = slabgen.get_slabs()

    # Phase diagram analysis
    entries = mpr.get_entries_in_chemsys(struct.composition.chemical_system)
    from pymatgen.analysis.phase_diagram import PhaseDiagram
    pd = PhaseDiagram(entries)

Additional Resources

Best Practices Summary

  1. Always use context manager: Use with MPRester() as mpr:
  2. Store API key as environment variable: Never hardcode API keys
  3. Batch queries: Request multiple items at once when possible
  4. Cache results: Save frequently used data locally
  5. Handle errors: Wrap API calls in try-except blocks
  6. Be specific: Use filters to limit results and reduce data transfer
  7. Check data availability: Not all properties are available for all materials