12 KiB
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
- Visit https://next-gen.materialsproject.org/
- Create an account or log in
- Navigate to your dashboard/settings
- Generate an API key
- 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
- API Documentation: https://docs.materialsproject.org/
- Materials Project Website: https://next-gen.materialsproject.org/
- GitHub: https://github.com/materialsproject/api
- Forum: https://matsci.org/
Best Practices Summary
- Always use context manager: Use
with MPRester() as mpr: - Store API key as environment variable: Never hardcode API keys
- Batch queries: Request multiple items at once when possible
- Cache results: Save frequently used data locally
- Handle errors: Wrap API calls in try-except blocks
- Be specific: Use filters to limit results and reduce data transfer
- Check data availability: Not all properties are available for all materials