def robocrystallographer( structure: Structure, condenser_kwargs: Optional[dict] = None, describer_kwargs: Optional[dict] = None, ) -> str: """Gets the robocrystallographer description of a structure. Args: structure: A structure. condenser_kwargs: Keyword arguments that will be passed to :obj:`robocrys.condense.StructureCondenser`. describer_kwargs: Keyword arguments that will be passed to :obj:`robocrys.describe.StructureDescriber`. Returns: The description. """ condenser_kwargs = condenser_kwargs if condenser_kwargs else {} describer_kwargs = describer_kwargs if describer_kwargs else {} sc = StructureCondenser(**condenser_kwargs) describer = StructureDescriber(**describer_kwargs) if not any( [hasattr(s, "oxi_state") for s in structure.composition.elements]): try: structure.add_oxidation_state_by_guess(max_sites=-80) except ValueError: warnings.warn("Could not add oxidation states!") condensed_structure = sc.condense_structure(structure) description = describer.describe(condensed_structure) print(description) return description
def run_robocrys_analysis(new_store_contents): print("Robocrys callback fired") struct = self.from_data(new_store_contents) try: condenser = StructureCondenser() describer = StructureDescriber() condensed_structure = condenser.condense_structure(struct) description = describer.describe(condensed_structure) except Exception as exc: description = str(exc) return MessageContainer( MessageBody([ f"{description} – ", html.A( f"🤖 robocrys v{robocrys_version}", href= "https://github.com/hackingmaterials/robocrystallographer", style={"white-space": "nowrap"}, ), ]), kind="dark", )
def test_grammar_and_punctuation(self): """Check common grammatical errors are not present""" d = StructureDescriber() description = d.describe(self.tin_dioxide) self.assertTrue(".." not in description) self.assertTrue(" " not in description) self.assertTrue(". ." not in description) description = d.describe(self.mapi) self.assertTrue(".." not in description) self.assertTrue(" " not in description) self.assertTrue(". ." not in description)
class RobocrysBuilder(MapBuilder): def __init__(self, materials, robocrys, **kwargs): """Runs robocrystallographer to get the condensed structure and structure description. Args: materials (Store): Store of materials documents. robocrys (Store): Store of condensed structure and text structure description. **kwargs: Keyword arguments that will get passed to the builder super method. """ self.materials = materials self.robocrys = robocrys self.condenser = StructureCondenser() self.describer = StructureDescriber(describe_symmetry_labels=False) super().__init__(source=materials, target=robocrys, ufn=self.calc, projection=["structure"], **kwargs) def calc(self, item): """Calculates robocrystallographer on an item. Args: item (dict): A dict with a task_id and a structure. Returns: dict: The robocrystallographer information dict with they keys: - ``"condensed_structure"``: The condensed structure dictionary. - ``"description"``: The text description. """ self.logger.debug("Running robocrys on {}".format( item[self.materials.key])) structure = Structure.from_dict(item["structure"]) doc = {"_robocrys_version": robocrys_version} try: self.logger.debug("Adding oxidation states for {}".format( item[self.materials.key])) structure.add_oxidation_state_by_guess(max_sites=-80) except ValueError: self.logger.warning("Could not add oxidation states for {}".format( item[self.materials.key])) condensed_structure = self.condenser.condense_structure(structure) description = self.describer.describe(condensed_structure) doc.update({ "condensed_structure": condensed_structure, "description": description }) return doc
def update_contents(self, new_store_contents): struct = self.from_data(new_store_contents) condenser = StructureCondenser() describer = StructureDescriber() condensed_structure = condenser.condense_structure(struct) description = describer.describe(condensed_structure) return MessageContainer(MessageBody([ f"{description} – ", html.A( f"🤖 robocrys v{robocrys_version}", href="https://github.com/hackingmaterials/robocrystallographer", style={"white-space": "nowrap"}, ), ]), kind="dark")
def update_contents(self, new_store_contents): struct = self.from_data(new_store_contents) condenser = StructureCondenser() describer = StructureDescriber() condensed_structure = condenser.condense_structure(struct) description = describer.describe(condensed_structure) return html.Blockquote( [ f"{description} – ", html.A( f"🤖 robocrys v{robocrys_version}", href="https://github.com/hackingmaterials/robocrystallographer", style={"white-space": "nowrap"}, ), ], className="mpc-blockquote", )
def __init__(self, materials, robocrys, **kwargs): """Runs robocrystallographer to get the condensed structure and structure description. Args: materials (Store): Store of materials documents. robocrys (Store): Store of condensed structure and text structure description. **kwargs: Keyword arguments that will get passed to the builder super method. """ self.materials = materials self.robocrys = robocrys self.condenser = StructureCondenser() self.describer = StructureDescriber(describe_symmetry_labels=False) super().__init__(source=materials, target=robocrys, ufn=self.calc, projection=["structure"], **kwargs)
def test_describe(self): """Broad tests to check the right information is in the description.""" # test general d = StructureDescriber( describe_oxidation_states=True, describe_symmetry_labels=True, return_parts=False, bond_length_decimal_places=2, fmt="raw", ) description = d.describe(self.tin_dioxide) self.assertTrue("Rutile" in description) self.assertTrue("SnO2" in description) self.assertTrue("tetragonal" in description) self.assertTrue("P4_2/mnm" in description) self.assertTrue("Sn(1)4+" in description) self.assertTrue("equivalent" in description) self.assertTrue("corner" in description) self.assertTrue("edge" in description) self.assertTrue("Sn(1)–O(1)" in description) self.assertTrue("2.09" in description) # test different settings d = StructureDescriber( describe_oxidation_states=False, describe_symmetry_labels=True, return_parts=False, bond_length_decimal_places=4, fmt="raw", ) description = d.describe(self.tin_dioxide) self.assertTrue("Sn(1)" in description) self.assertTrue("Sn(1)–O(1)" in description) self.assertTrue("2.0922" in description) # test different settings d = StructureDescriber( describe_oxidation_states=True, describe_symmetry_labels=False, return_parts=False, bond_length_decimal_places=2, fmt="latex", ) description = d.describe(self.tin_dioxide) self.assertTrue(r"Sn^{4+}" in description) self.assertTrue("Sn–O" in description) # test return parts d = StructureDescriber( describe_oxidation_states=True, describe_symmetry_labels=True, return_parts=True, bond_length_decimal_places=2, fmt="raw", ) description = d.describe(self.tin_dioxide) self.assertTrue("Rutile" in description["mineral"]) self.assertTrue("SnO2" in description["mineral"]) self.assertTrue("tetragonal" in description["mineral"]) self.assertTrue("P4_2/mnm" in description["mineral"]) self.assertTrue("" == description["component_makeup"]) self.assertTrue("Sn(1)4+" in description["components"]) self.assertTrue("equivalent" in description["components"]) self.assertTrue("corner" in description["components"]) self.assertTrue("edge" in description["components"]) self.assertTrue("Sn(1)–O(1)" in description["components"]) self.assertTrue("2.09" in description["components"])