def get_composition_from_string(comp_str): """validate and return composition from string `comp_str`.""" from pymatgen.core import Composition, Element comp = Composition(comp_str) for element in comp.elements: Element(element) formula = comp.get_integer_formula_and_factor()[0] comp = Composition(formula) return "".join( [ "{}{}".format(key, int(value) if value > 1 else "") for key, value in comp.as_dict().items() ] )
def update_displayed_composition(*args): kwargs = self.reconstruct_kwargs_from_state() comp_dict = {} for k, v in kwargs.items(): if "comp" in k: # keys are encoded like "comp-Ag" el = k.split("-")[1] comp_dict[el] = v comp_dict = comp_dict or None if not comp_dict: return "" try: comp = Composition(comp_dict) formula = Composition( comp.get_integer_formula_and_factor()[0]).reduced_formula except: return html.Small(f"Invalid composition selected.", style={"color": "red"}) return html.Small( f"Pourbaix composition set to {unicodeify(formula)}.")
async def formula_autocomplete( text: str = Query( ..., description="Text to run against formula autocomplete", ), limit: int = Query( 10, description="Maximum number of matches to show. Defaults to 10", ), ): comp = Composition(text) ind_str = [] if len(comp) == 1: d = comp.get_integer_formula_and_factor() s = d[0] + str(int(d[1])) if d[1] != 1 else d[0] ind_str.append(s) else: comp_red = comp.reduced_composition.items() for (i, j) in comp_red: if j != 1: ind_str.append(i.name + str(int(j))) else: ind_str.append(i.name) final_terms = ["".join(entry) for entry in permutations(ind_str)] pipeline = [ { "$search": { "index": "formula_autocomplete", "autocomplete": { "path": "formula_pretty", "query": final_terms, "tokenOrder": "any", }, } }, { "$group": { "_id": "$formula_pretty", } }, { "$project": { "score": { "$strLenCP": "$_id" } } }, { "$sort": { "score": 1 } }, { "$limit": limit }, ] self.store.connect() data = list( self.store._collection.aggregate(pipeline, allowDiskUse=True)) response = {"data": data} return response