-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
18,027 additions
and
1,343 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,65 @@ | ||
import os.path | ||
from monty.serialization import loadfn | ||
|
||
from pymatgen.core.structure import Structure | ||
from pymatgen.analysis.bond_valence import BVAnalyzer | ||
from pymatgen.core.periodic_table import Specie | ||
from pymatgen import __version__ as pymatgen_version | ||
|
||
from maggma.builder import Builder | ||
from maggma.examples.builders import MapBuilder | ||
from maggma.validator import JSONSchemaValidator | ||
|
||
|
||
BOND_VALENCE_SCHEMA = { | ||
"title": "bond_valence", | ||
"type": "object", | ||
"properties": | ||
{ | ||
"task_id": {"type": "string"}, | ||
"method": {"type": "string"}, | ||
"possible_species": {"type": "array", "items": {"type": "strinig"}}, | ||
"possible_valences": {"type": "array", "items": {"type": "number"}}, | ||
"successful": {"type": "boolean"}, | ||
"pymatgen_version": {"type": "string"}, | ||
}, | ||
"required": ["task_id", "successful", "pymatgen_version"] | ||
} | ||
MODULE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__))) | ||
BOND_VALENCE_SCHEMA = os.path.join(MODULE_DIR, "schema", "bond_valence.json") | ||
|
||
|
||
class BondValenceBuilder(Builder): | ||
class BondValenceBuilder(MapBuilder): | ||
""" | ||
Calculate plausible oxidation states from structures. | ||
""" | ||
|
||
def __init__(self, materials, bond_valence, | ||
query=None, **kwargs): | ||
def __init__(self, materials, bond_valence, **kwargs): | ||
|
||
self.materials = materials | ||
self.bond_valence = bond_valence | ||
self.query = query or {} | ||
|
||
super().__init__(sources=[materials], | ||
targets=[bond_valence], | ||
**kwargs) | ||
|
||
def get_items(self): | ||
self.bond_valence.validator = JSONSchemaValidator(loadfn(BOND_VALENCE_SCHEMA)) | ||
super().__init__(source=materials, target=bond_valence, ufn=self.calc, projection=["structure"], **kwargs) | ||
|
||
materials = self.materials.query(criteria=self.query, | ||
properties=["task_id", "structure"]) | ||
# All relevant materials that have been updated since bond valences | ||
# were last calculated | ||
q = dict(self.query) | ||
q.update(self.materials.lu_filter(self.bond_valence)) | ||
new_keys = list(self.materials.distinct(self.materials.key, q)) | ||
|
||
materials = self.materials.query(criteria={self.materials.key: {'$in': new_keys}}, | ||
properties=["task_id", "structure"]) | ||
|
||
self.total = materials.count() | ||
self.logger.info("Found {} new materials for bond valence analysis".format(self.total)) | ||
def calc(self, item): | ||
s = Structure.from_dict(item['structure']) | ||
|
||
for material in materials: | ||
yield material | ||
d = {"pymatgen_version": pymatgen_version, "successful": False} | ||
|
||
def process_item(self, item): | ||
s = Structure.from_dict(item['structure']) | ||
try: | ||
bva = BVAnalyzer() | ||
valences = bva.get_valences(s) | ||
possible_species = {str(Specie(s[idx].specie, oxidation_state=valence)) | ||
for idx, valence in enumerate(valences)} | ||
possible_species = { | ||
str(Specie(s[idx].specie, oxidation_state=valence)) for idx, valence in enumerate(valences) | ||
} | ||
|
||
method = "BVAnalyzer" | ||
|
||
d["successful"] = True | ||
d["bond_valence"] = { | ||
"possible_species": list(possible_species), | ||
"possible_valences": valences, | ||
"method": "oxi_state_guesses" | ||
} | ||
|
||
except ValueError: | ||
try: | ||
first_oxi_state_guess = s.composition.oxi_state_guesses()[0] | ||
valences = [first_oxi_state_guess[site.species_string] for site in s] | ||
possible_species = {str(Specie(el, oxidation_state=valence)) | ||
for el, valence in first_oxi_state_guess.items()} | ||
method = "oxi_state_guesses" | ||
except: | ||
return { | ||
"task_id": item['task_id'], | ||
"pymatgen_version": pymatgen_version, | ||
"successful": False | ||
possible_species = { | ||
str(Specie(el, oxidation_state=valence)) for el, valence in first_oxi_state_guess.items() | ||
} | ||
d["successful"] = True | ||
d["bond_valence"] = { | ||
"possible_species": list(possible_species), | ||
"possible_valences": valences, | ||
"method": "oxi_state_guesses" | ||
} | ||
except: | ||
pass | ||
|
||
return { | ||
"task_id": item['task_id'], | ||
"possible_species": list(possible_species), | ||
"possible_valences": valences, | ||
"method": method, | ||
"pymatgen_version": pymatgen_version, | ||
"successful": True | ||
} | ||
|
||
def update_targets(self, items): | ||
self.logger.debug("Updating {} bond valence documents".format(len(items))) | ||
self.bond_valence.update(docs=items, key=['task_id']) | ||
return d |
Oops, something went wrong.