Initial commit
This commit is contained in:
517
skills/pymatgen/references/materials_project_api.md
Normal file
517
skills/pymatgen/references/materials_project_api.md
Normal file
@@ -0,0 +1,517 @@
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
export MP_API_KEY="your_api_key_here"
|
||||
```
|
||||
|
||||
Or add to your shell configuration file (~/.bashrc, ~/.zshrc, etc.)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Initialization
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
with MPRester() as mpr:
|
||||
# Get piezoelectric materials
|
||||
materials = mpr.materials.piezoelectric.search(
|
||||
piezoelectric_modulus=(1, 100)
|
||||
)
|
||||
```
|
||||
|
||||
## Surface Properties
|
||||
|
||||
```python
|
||||
with MPRester() as mpr:
|
||||
# Get surface data
|
||||
surfaces = mpr.materials.surface_properties.search(
|
||||
material_ids=["mp-149"]
|
||||
)
|
||||
```
|
||||
|
||||
## Molecule Data (For Molecular Materials)
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
# 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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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:
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user