Source code for PyGamLab.databases.Material_projects


import json
from typing import List, Optional
from mp_api.client import MPRester



    
[docs] class MaterialsProject_Explorer: """ A unified interface to search and fetch various material properties from the Materials Project. This class allows searching by elements, chemical formula, or specific MP-IDs, and fetching electronic, mechanical, thermodynamic, and structural properties. Attributes ---------- api_key : str, optional API key for accessing Materials Project (if required). mpr : MPRester MPRester instance for querying the API. results : dict Stores the latest fetched data for a material. Examples -------- >>> explorer = MaterialsProject_Explorer(api_key="YOUR_API_KEY") >>> results = explorer.search_materials(formula="MoS2") >>> explorer.fetch_electronic_properties("mp-123") {'mp-id': 'mp-123', 'band_gap': 1.23, ...} >>> all_data = explorer.fetch_all_data("mp-123") >>> all_data['electronic_prop']['band_gap'] 1.23 >>> explorer.close() """ def __init__(self, api_key: Optional[str] = None): """ Initialize the MaterialsProject_Explorer. Parameters ---------- api_key : str, optional API key for Materials Project access. If None, assumes local access or environment key. """ self.api_key = api_key self.mpr = MPRester(api_key) if api_key else MPRester() self.results = { 'electronic_prop': {}, 'mechanical_prop': {}, 'thermo_prop': {}, 'structure': {}, 'meta_data': {} }
[docs] def search_materials(self, elements: Optional[List[str]] = None, formula: Optional[str] = None, mp_ids: Optional[List[str]] = None, max_results: int = 5,description=True) -> List[str]: """ Search for materials by elements, chemical formula, or MP-IDs. Parameters ---------- elements : list[str], optional List of chemical elements to search for (e.g., ["Mo", "S"]). formula : str, optional Chemical formula to search for (e.g., "MoS2"). mp_ids : list[str], optional List of Materials Project IDs to search directly. max_results : int, default 5 Maximum number of results to return. description : bool, default True If True, returns a list of dictionaries with basic material info. If False, returns only a list of material IDs. Returns ------- list[str] or list[dict] List of material IDs or detailed descriptions for each result. Example ------- >>> explorer = MaterialsProject_Explorer() >>> explorer.search_materials(formula="MoS2") [{'mp-id': 'mp-123', 'system': 'Mo-S', 'band_gap (eV)': 1.23, ...}] """ material_ids = [] if mp_ids: material_ids.extend(mp_ids) return list(set(material_ids)) if formula: docs = self.mpr.materials.summary.search(formula=formula, num_chunks=1, chunk_size=max_results) material_ids.extend([d.material_id for d in docs]) if description==True: rows = [] for d in docs: rows.append({ "mp-id": d.material_id.string, "system": d.chemsys, "band_gap (eV)": getattr(d, "band_gap", None), "Ehull (eV/atom)": getattr(d, "energy_above_hull", None), "magnetism": getattr(d, "magnetic_ordering", None), "theoretical": getattr(d, "theoretical", None) }) return rows if elements: docs = self.mpr.materials.summary.search(elements=elements, num_chunks=1, chunk_size=max_results) material_ids.extend([d.material_id for d in docs]) if description==True: rows = [] for d in docs: rows.append({ "mp-id": d.material_id.string, "system": d.chemsys, "band_gap (eV)": getattr(d, "band_gap", None), "Ehull (eV/atom)": getattr(d, "energy_above_hull", None), "magnetism": getattr(d, "magnetic_ordering", None), "theoretical": getattr(d, "theoretical", None) }) return rows
[docs] def fetch_electronic_properties(self, mp_id: str) -> dict: """ Fetch electronic properties for a given Materials Project ID. Parameters ---------- mp_id : str Materials Project ID (e.g., "mp-123"). Returns ------- dict Electronic properties including band structure, density of states, bandgap, etc. Example ------- >>> explorer.fetch_electronic_properties("mp-123") {'mp-id': 'mp-123', 'band_gap': 1.23, 'DOS': {...}, ...} """ try: electronic_results={} electronic_results['mp-id']=mp_id docs = self.mpr.materials.electronic_structure.search(material_ids=[mp_id]) doc=docs[0].dict() for key,value in doc.items(): electronic_results[key]=value except Exception: electronic_results['electronic_structure']=None try: dos = self.mpr.get_dos_by_material_id(mp_id) dos_dict = dos.dict() for key,value in dos_dict.items(): electronic_results[key]=value except Exception: electronic_results['DOS']=None try: bs = self.mpr.get_bandstructure_by_material_id(mp_id) bs_dict=bs.as_dict() for key,value in bs_dict.items(): electronic_results[key]=value except Exception: electronic_results['bandstructure']=None self.results['electronic_prop']=electronic_results return electronic_results
[docs] def fetch_mechanical_properties(self, mp_id: str) -> dict: """ Fetch mechanical properties for a given Materials Project ID. Parameters ---------- mp_id : str Materials Project ID. Returns ------- dict or None Mechanical properties including elastic tensors, bulk/shear modulus, Poisson ratio. Example ------- >>> explorer.fetch_mechanical_properties("mp-123") {'mp-id': 'mp-123', 'elastic_tensor': [...], ...} """ try: docs = self.mpr.materials.elasticity.search(material_ids=[mp_id]) doc = docs[0].dict() mechanical_prop=doc mechanical_prop['mp-id']=mp_id self.results['mechanical_prop']=doc except Exception as e: self.results['mechanical_prop']=None return None return mechanical_prop
[docs] def fetch_thermodynamic_properties(self, mp_id: str) -> dict: """ Fetch thermodynamic properties for a given Materials Project ID. Parameters ---------- mp_id : str Materials Project ID. Returns ------- dict or None Thermodynamic properties including formation energy, heat capacities, etc. Example ------- >>> explorer.fetch_thermodynamic_properties("mp-123") {'mp-id': 'mp-123', 'formation_energy_per_atom': -2.34, ...} """ try: docs = self.mpr.materials.thermo.search(material_ids=[mp_id]) doc = docs[0].dict() thermo_prop=doc thermo_prop['mp-id']=mp_id self.results['thermo_prop']=thermo_prop except Exception as e: self.results['thermo_prop']=None return None return thermo_prop
[docs] def fetch_structure(self, mp_id: str) -> dict: """ Fetch structural properties for a given Materials Project ID. Parameters ---------- mp_id : str Materials Project ID. Returns ------- list of dict or None Structure data in pymatgen format. Example ------- >>> explorer.fetch_structure("mp-123") [{'structure_pymatgen': Structure(...)}] """ try: struct = self.mpr.get_structure_by_material_id(mp_id) self.results["structure"]=[{'mp-id':mp_id,'structure_pymatgen': struct}] except Exception as e: self.results["structure"]=None return None return [{'structure_pymatgen': struct}]
[docs] def fetch_all_data(self,mp_id): """ Fetch all available data (electronic, mechanical, thermodynamic, structure) for a material. Parameters ---------- mp_id : str Materials Project ID. Returns ------- dict Dictionary with keys: 'electronic_prop', 'mechanical_prop', 'thermo_prop', 'structure', 'meta_data'. Example ------- >>> all_data = explorer.fetch_all_data("mp-123") >>> all_data['electronic_prop']['band_gap'] 1.23 """ electronic=self.fetch_electronic_properties(mp_id) mechanical=self.fetch_mechanical_properties(mp_id) thermo=self.fetch_thermodynamic_properties(mp_id) structure=self.fetch_structure(mp_id) return self.results
[docs] def close(self): """ Close the underlying MPRester session. Example ------- >>> explorer.close() """ self.mpr.session.close()