### Get site fingerprints format examples Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Examples of the return format for site fingerprints based on the as_dict parameter. ```python [{'op': val}] ``` ```python [site_index][op_index] ``` -------------------------------- ### get_site_summary(site_index) Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets a summary of the site information. ```APIDOC ## get_site_summary(site_index) ### Description Gets a summary of the site information. ### Parameters - **site_index** (int) - Required - The site index (zero based). ### Returns - (dict[str, Any]) - A summary dictionary of the site. ``` -------------------------------- ### Get component site descriptions Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/describer.html Generates a descriptive string for all sites within a specific component, identifying inequivalent sites. ```python def get_component_description( self, component_index: int, single_component: bool = False ) -> str: """Gets the descriptions of all sites in a component. Args: component_index: The index of the component single_component: Whether the structure contains only a single component. Returns: The description for all sites in the components. """ desc = [] first_group = True for site_group in self._da.get_component_site_groups(component_index): if len(site_group.sites) == 1: desc.append(self.get_site_description(site_group.sites[0])) else: element = get_formatted_el( site_group.element, "", use_oxi_state=self.describe_oxidation_state, use_sym_label=False, fmt=self.fmt, ) s_there = "there" if first_group and not single_component else "There" s_count = en.number_to_words(len(site_group.sites)) # type: ignore[arg-type] desc.append(f"{s_there} are {s_count} inequivalent {element} sites.") ``` -------------------------------- ### Get all component descriptions Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/describer.html Retrieves a comprehensive string description of all components within a structure, handling single-component cases and formatting formulas. ```python def get_all_component_descriptions(self) -> str: """Gets the descriptions of all components in the structure. Returns: A description of all components in the structure. """ if len(self._da.components) == 1: return self.get_component_description( self._da.get_component_groups()[0].components[0].index, single_component=True, ) component_groups = self._da.get_component_groups() component_descriptions = [] for group in component_groups: for component in group.components: if group.molecule_name: # don't describe known molecules continue formula = group.formula group_count = group.count component_count = component.count shape = dimensionality_to_shape[group.dimensionality] if self.fmt == "latex": formula = latexify(formula) elif self.fmt == "unicode": formula = unicodeify(formula) elif self.fmt == "html": formula = htmlify(formula) if group_count == component_count: s_filler = "the" if group_count == 1 else "each" else: s_filler = f"{en.number_to_words(component_count)} of the" shape = en.plural(shape) desc = f"In {s_filler} {formula} {shape}, " desc += self.get_component_description(component.index) component_descriptions.append(desc) return " ".join(component_descriptions) ``` -------------------------------- ### Get octahedral tilt description Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/describer.html Calculates and describes octahedral tilting angles for corner-sharing octahedra. ```python def get_octahedral_tilt_description( self, site_index: int, ) -> str: """Gets a description of octahedral tilting angles between two sites. Currently only implemented for corner-sharing octahedra. Will throw an error if the two sites are not next nearest neighbors. Args: site_index: An inequivalent site index. Returns: A description of the octahedral tilting angles. """ nnn_details = self._da.get_next_nearest_neighbor_details( site_index, group=not self.describe_symmetry_labels ) to_sites = [ site for nnn_site in nnn_details for site in nnn_site.sites if nnn_site.geometry == "octahedral" and nnn_site.connectivity == "corner" ] angles = self._da.get_angle_details(site_index, to_sites, "corner") discrete_angles = list(set(self._rounded_angles(angles))) tilts = [abs(180 - angle) for angle in discrete_angles] if not tilts: return "" # if only one bond length if len(tilts) == 1: if tilts[0] == 0: return "The corner-sharing octahedra are not tilted" return "The corner-sharing octahedral tilt angles are {}".format( self._angle_to_string(tilts[0]) ) # otherwise just detail the spread of bond lengths return "The corner-sharing octahedral tilt angles range from {}".format( self._angle_range_to_string(min(tilts), max(tilts)) ) ``` -------------------------------- ### get_octahedral_tilt_description(site_index) Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.html Gets a description of octahedral tilting angles between two sites. ```APIDOC ## get_octahedral_tilt_description(site_index) ### Description Gets a description of octahedral tilting angles between two sites. Currently only implemented for corner-sharing octahedra. Throws an error if sites are not next nearest neighbors. ### Parameters - **site_index** (int) - Required - An inequivalent site index. ### Returns - **str**: A description of the octahedral tilting angles. ``` -------------------------------- ### Get all bond distance summaries Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Returns a dictionary mapping site indices to their bond distance summaries. ```python { from_site: { to_site: distances } } ``` -------------------------------- ### Condensed structure JSON example Source: https://hackingmaterials.lbl.gov/robocrystallographer/format.html A sample JSON object representing a condensed crystal structure for Molybdenite. ```json { 'mineral': { 'type': 'Molybdenite', 'distance': -1, 'n_species_type_match': True, 'simplified': False }, 'formula': 'MoS2', 'spg_symbol': 'P6_3/mmc', 'crystal_system': 'hexagonal', 'dimensionality': 2, 'sites': { 0: {'element': 'Mo4+', 'geometry': { 'distorted': True, 'type': 'pentagonal pyramidal' }, 'nn': [2, 2, 2, 2, 2, 2], 'nnn': {'edge': [0, 0, 0, 0, 0, 0]}, 'poly_formula': 'S6', 'sym_labels': (1,) }, 2: {'element': 'S2-', 'geometry': { 'distorted': False, 'type': '3-coordinate' }, 'nn': [0, 0, 0], 'nnn': {'corner': [2, 2, 2, ...], 'face': [2]}, 'poly_formula': None, 'sym_labels': (1,) } }, 'distances': { 0: {2: [2.42, 2.42, 2.42, ...]}, 2: {0: [2.42, 2.42, 2.42]} }, 'angles': { 0: {0: {'edge': [82.60, 82.60, 82.60, ...]}}, 2: {2: {'corner': [135.20, 82.60, 135.20, ...], 'face': [80.70, 80.70, 80.70]}}}, 'nnn_distances': { 0: {0: {'edge': [3.19, 3.19, 3.19, ...]}}, 2: {2: {'face': [3.13], 'corner': [3.19, 4.47, 3.19, ...]}}}, 'components': { 0: {'formula': 'MoS2', 'sites': [0, 2] 'dimensionality': 2, 'molecule_name': None, 'orientation': (0, 0, 1) } }, 'component_makeup': [0, 0], 'vdw_heterostructure_info': { 'intercalant_formulas': [], 'num_repetitions': 2, 'repeating_unit': ['MoS2'] } } ``` -------------------------------- ### Define condensed component data structure Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/condenser.html Example of the dictionary structure returned by the component condensation process. ```python { 0: { 'formula': 'MoS2', 'sites': [0, 2] 'dimensionality': 2, 'molecule_name': None, 'orientation': (0, 0, 1) } } ``` -------------------------------- ### Get all next nearest neighbor distance summaries Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Returns a dictionary mapping site indices to next nearest neighbor distance summaries. ```python { from_site: { to_site: { connectivity: distances } } } ``` -------------------------------- ### Get van der Waals heterostructure information Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/component.html Analyzes a list of structure components to determine stacking order, repeating units, and intercalant formulas. ```python def get_vdw_heterostructure_information( components: list[Component], use_iupac_formula: bool = True, use_common_formulas: bool = True, inc_ordered_components: bool = False, inc_intercalants: bool = False, ) -> dict[str, Any]: """Gets information about ordering of components in a vdw heterostructure. Args: components: A list of structure components, generated using :obj:`pymatgen.analysis.dimensionality.get_structure_components` with ``inc_orientation=True``. use_iupac_formula (bool, optional): Whether to order formulas by the iupac "electronegativity" series, defined in Table VI of "Nomenclature of Inorganic Chemistry (IUPAC Recommendations 2005)". This ordering effectively follows the groups and rows of the periodic table, except the Lanthanides, Actanides and hydrogen. If set to ``False``, the elements will be ordered according to the electronegativity values. use_common_formulas: Whether to use the database of common formulas. The common formula will be used preferentially to the iupac or reduced formula. inc_ordered_components: Whether to return a list of the ordered components. If False, just the component formulas will be returned. inc_intercalants: Whether to return a list of the intercalants. If False, just the intercalant formulas will be returned. Returns: Information on the heterostructure, as an :obj:`dict` with they keys: - ``"repeating_unit"`` (``list[str]``): A :obj:`List` of formulas of the smallest repeating series of components. For example. if the structure consists of A and B components ordered as "A B A B A B", the repeating unit is "A B". - ``"num_repetitions"`` (:obj:`int`): The number of repetitions of the repeating unit that forms the overall structure. For example. if the structure consists of A and B components ordered as "A B A B A B", the number of repetitions is 3. - ``"intercalant_formulas"`` (:obj:`list[str]`): The formulas of the intercalated compounds. - ``"ordered_components"`` (``list[component]``): If ``inc_ordered_components``, a :obj:`List` of components, ordered as they appear in the heteostructure stacking direction. - ``"intercalants"`` (``list[component]``: If ``inc_intercalants``, a :obj:`List` of intercalated components. """ if not components_are_vdw_heterostructure(components): raise ValueError("Components do not form a heterostructure.") try: millers = {c["orientation"] for c in components if c["dimensionality"] == 2} except KeyError as exc: if "orientation" in str(exc): raise KeyError( "Components not generated with inc_orientation=True" ) from exc raise exc if len(millers) != 1: raise ValueError("2D components don't all have the same orientation.") cart_miller = ( components[0]["structure_graph"] .structure.lattice.get_cartesian_coords(millers.pop()) .tolist() ) # plane is used to find the distances of all components along a certain axis # should use normal vector of plane to get exact distances but we just care # about relative distances. def distances_to_plane(points): return [np.dot(cart_miller, pp) for pp in points] min_distances = [ min(distances_to_plane(c["structure_graph"].structure.cart_coords)) for c in components ] # sort the components by distance to plane ordering = np.argsort(min_distances) ordered_components = [components[x] for x in ordering] # only consider the layered components formulae ordered_layers = [c for c in ordered_components if c["dimensionality"] == 2] ordered_layers_formula = [ get_component_formula( c, use_iupac_formula=use_iupac_formula, use_common_formulas=use_common_formulas, ) for c in ordered_layers ] num_layer_formulas = len(set(ordered_layers_formula)) repeating_formula = ordered_layers_formula num_repetitions = 1 ``` -------------------------------- ### Get component site groups Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/adapter.html Retrieves a list of SiteGroup objects summarizing sites within a component, grouped by element. ```python def get_component_site_groups(self, component_index: int) -> list[SiteGroup]: """Gets a summary of the sites in a component. Returns: The sites, grouped together by element. The data will be returned as a :obj:`list` of ``SiteGroup`` objects, each with the attributes: - ``count`` (``int``): The total number of sites in this group. - ``element`` (``str``): The site element. - ``sites`` (``list[int]``): A list of site indices in this group. """ sites = list(set(self.components[component_index]["sites"])) grouped_sites = defaultdict(list) for site_index in sites: grouped_sites[self.elements[site_index]].append(site_index) site_groups = [] for element, group in grouped_sites.items(): site_groups.append( SiteGroup( count=sum(sites.count(site_index) for site_index in group), element=element, sites=group, ) ) return sorted(site_groups, key=self._site_order) ``` -------------------------------- ### Get bond length description Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/describer.html Generates a description of bond lengths between two sets of sites, optionally filtering out previously described bonds. ```python [docs] def get_bond_length_description(self, from_site: int, to_sites: list[int]) -> str: """Gets a description of the bond lengths between two sets of sites. Args: from_site: An inequivalent site index. to_sites: A :obj:`list` of site indices. The site indices should all be for the same element. Returns: A description of the bond lengths or an empty string if :attr:`StructureDescriber.only_describe_bonds_once` is ``True`` and all all bond lengths have already been described. """ if self.only_describe_bonds_once: to_sites = self._filter_seen_bonds(from_site, to_sites) if not to_sites: return "" ``` -------------------------------- ### Get all connectivity angle summaries Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Returns a dictionary mapping site indices to connectivity angle summaries between sites and their next nearest neighbors. ```python { from_site: { to_site: { connectivity: angles } } } ``` -------------------------------- ### Initialize DescriptionAdapter Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/describe/adapter.html Initializes the adapter with condensed structure data and configuration for IUPAC ordering. ```python def __init__( self, condensed_structure: dict[str, Any], use_iupac_ordering: bool = True ): super().__init__(condensed_structure) self.use_iupac_ordering = use_iupac_ordering self.sym_labels = { site_index: self.get_sym_label(site_index) for site_index in self.sites } ``` -------------------------------- ### get_site_geometry(site_index) Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets the bonding geometry of a site. ```APIDOC ## get_site_geometry(site_index) ### Description Gets the bonding geometry of a site (e.g., octahedral, square-planar). ### Parameters - **site_index** (int) - Required - The site index (zero based). ### Returns - (dict[str, str | float]) - Dictionary containing 'type' (geometry_type) and 'likeness' (order_parameter). ``` -------------------------------- ### BaseAdapter.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/adapter.html Initializes the BaseAdapter with condensed structure data. ```APIDOC ## BaseAdapter(condensed_structure: dict[str, Any]) ### Description Initializes the adapter with structure data produced by the StructureCondenser. ### Parameters - **condensed_structure** (dict) - Required - The condensed structure data. ``` -------------------------------- ### robocrys.condense.component.get_structure_inequiv_components Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets and counts the structurally inequivalent components. ```APIDOC ## get_structure_inequiv_components(components, use_structure_graph=False, fingerprint_tol=0.01) ### Description Gets and counts the structurally inequivalent components. Supports matching through StructureMatcher or by a combined structure graph/site fingerprint approach. ### Parameters - **components** (list[dict[str, Any]]) - Required - A list of structure components, generated using pymatgen.analysis.dimensionality.get_structure_components. - **use_structure_graph** (bool) - Optional - Whether to use the bonding graph and site fingerprints to determine if components are structurally equivalent. - **fingerprint_tol** (float) - Optional - The fingerprint tolerance to determine whether two components have a matching fingerprint. ### Returns - **list[dict[str, Any]]** - A list of the structurally inequivalent components. ``` -------------------------------- ### SiteAnalyzer.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Initializes the SiteAnalyzer with a bonded structure and configuration parameters for symmetry and geometry analysis. ```APIDOC ## SiteAnalyzer(bonded_structure, use_symmetry_equivalent_sites=False, symprec=0.01, minimum_geometry_op=0.4, use_iupac_formula=True) ### Description Initializes the analyzer to extract information on site geometry and bonding. ### Parameters - **bonded_structure** (StructureGraph) - Required - A bonded structure with nearest neighbor data. - **use_symmetry_equivalent_sites** (bool) - Optional - Whether to use symmetry to determine if sites are inequivalent. - **symprec** (float) - Optional - Tolerance used when determining the symmetry of the structure. - **minimum_geometry_op** (float) - Optional - The minimum geometrical order parameter for a geometry match to be returned. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by the iupac electronegativity series. ``` -------------------------------- ### Display CLI Help Source: https://hackingmaterials.lbl.gov/robocrystallographer/cli.html Lists all supported command-line options for the robocrys program. ```bash robocrys -h ``` -------------------------------- ### robocrys.condense.component.get_component_formula Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets the reduced formula of a single component. ```APIDOC ## get_component_formula(component, use_iupac_formula=True, use_common_formulas=True) ### Description Gets the reduced formula of a single component. ### Parameters - **component** (dict[str, Any]) - Required - A structure component. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by the iupac electronegativity series. - **use_common_formulas** (bool) - Optional - Whether to use the database of common formulas. ### Returns - **str** - The formula of the component. ``` -------------------------------- ### robocrys.condense.component.get_formula_inequiv_components Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets and counts the inequivalent components based on their formula. ```APIDOC ## get_formula_inequiv_components(components, use_iupac_formula=True, use_common_formulas=True) ### Description Gets and counts the inequivalent components based on their formula. Note that the counting of compounds is different to in get_sym_inequiv_equivalent. ### Parameters - **components** (list[dict[str, Any]]) - Required - A list of structure components, generated using pymatgen.analysis.dimensionality.get_structure_components, with inc_site_ids=True. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by the iupac electronegativity series. - **use_common_formulas** (bool) - Optional - Whether to use the database of common formulas. ### Returns - **list[dict[str, Any]]** - A list of the compositionally inequivalent components with added 'count' and 'formula' fields. ``` -------------------------------- ### RobocrysFeaturizer.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/featurize/featurizer.html Initializes the RobocrysFeaturizer with optional condenser configuration and distortion tolerance. ```APIDOC ## RobocrysFeaturizer(condenser_kwargs=None, distorted_tol=0.6) ### Description Initializes the featurizer instance. ### Parameters - **condenser_kwargs** (dict) - Optional - Keyword arguments passed to StructureCondenser. - **distorted_tol** (float) - Optional - Threshold for classifying site geometry as distorted (default: 0.6). ``` -------------------------------- ### Initialize FeaturizerAdapter Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/featurize/adapter.html The class constructor requires condensed structure data and an optional distortion tolerance. ```python class FeaturizerAdapter(BaseAdapter): """Class to facilitate featurizing condensed structure data. Args: condensed_structure: The condensed structure data, formatted as produced by :meth:`robocrys.condense.StructureCondenser.condense_structure`. """ def __init__(self, condensed_structure: dict[str, Any], distorted_tol: float = 0.6): super().__init__(condensed_structure) self._all_sites = [ site for component_index in self.component_makeup for site in self.components[component_index]["sites"] ] self._distorted_tol = distorted_tol ``` -------------------------------- ### robocrys.condense.component.get_component_formula_and_factor Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets the reduced formula and factor of a single component. ```APIDOC ## get_component_formula_and_factor(component, use_iupac_formula=True, use_common_formulas=True) ### Description Gets the reduced formula and factor of a single component. ### Parameters - **component** (dict[str, Any]) - Required - A structure component. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by the iupac electronegativity series. - **use_common_formulas** (bool) - Optional - Whether to use the database of common formulas. ### Returns - **tuple** - The formula and factor of the component. ``` -------------------------------- ### get_site_description(site_index) Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.html Gets a description of the geometry and bonding of a specific site. ```APIDOC ## get_site_description(site_index) ### Description Gets a description of the geometry and bonding of a site. If the site likeness is less than distorted_tol, "distorted" is added to the description. ### Parameters - **site_index** (int) - Required - An inequivalent site index. ### Returns - **str**: A description of the geometry and bonding of a site. ``` -------------------------------- ### Initialize MoleculeNamer Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/molecule.html Instantiate the class to configure online lookup behavior and name source preferences. ```python class MoleculeNamer: name_sources = ("traditional", "iupac") def __init__( self, use_online_pubchem: bool = True, name_preference: tuple[str, ...] = name_sources, ): """Class to match molecule graphs to known molecule names. Args: use_online_pubchem: Whether to try using the Pubchem website for matching molecules if a match is not found in the offline database. Defaults to ``True``. Requires a working internet connection and for the ``pubchempy`` package to be installed. name_preference: The order of preference for determining compound names. Options are "traditional", and "iupac". If the first option is not available, the subsequent options will be used. Should be provided as a tuple of options, from 1st choice to last. """ db_file = import_resource_file("robocrys.condense") / "molecule_db.json.gz" self.molecule_db: dict[str, dict[str, str]] = loadfn(str(db_file)) self.matched_molecules: dict[str, str] = {} self.use_online_pubchem = use_online_pubchem # append the sources list to the end in case the user only supplies # a single preference self.name_preference = tuple(list(name_preference) + list(self.name_sources)) ``` -------------------------------- ### MoleculeNamer.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/molecule.html Initializes the MoleculeNamer instance with configuration for database lookups and naming preferences. ```APIDOC ## MoleculeNamer(use_online_pubchem=True, name_preference=('traditional', 'iupac')) ### Description Initializes the molecule namer. ### Parameters - **use_online_pubchem** (bool) - Optional - Whether to use Pubchem for matching if not found in the offline database. Defaults to True. - **name_preference** (tuple) - Optional - The order of preference for naming sources (e.g., 'traditional', 'iupac'). ``` -------------------------------- ### get_nnn_distance_summary(site_index) Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Gets the next nearest neighbor distance summary for a site. ```APIDOC ## get_nnn_distance_summary(site_index) ### Description Gets the next nearest neighbor distance summary for a site. ### Parameters - **site_index** (int) - Required - The site index (zero based). ### Returns - (dict[int, dict[str, list[float]]]) - The connectivity distance data for the site. ``` -------------------------------- ### Initialize SiteAnalyzer Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html The SiteAnalyzer class is initialized with a bonded structure and configuration parameters for symmetry and geometry analysis. ```python class SiteAnalyzer: """Class to extract information on site geometry and bonding. Attributes: symmetry_labels: A :obj:`dict` mapping the site indices to the symmetry label for that site. If two sites are symmetrically equivalent they share the same symmetry label. The numbering begins at 1 for each element in the structure. equivalent_sites: A :obj:`list` of indices mapping each site in the structure to a symmetrically or structurally equivalent site, depending on the value of ``use_symmetry_equivalent_sites``. Args: bonded_structure: A bonded structure with nearest neighbor data included. For example generated using :class:`pymatgen.analysis.local_env.CrystalNN` or :class:`pymatgen.analysis.local_env.VoronoiNN`. use_symmetry_equivalent_sites: Whether to use symmetry to determine if sites are inequivalent. If ``False``, the site geometry and (next) nearest neighbor information will be used. symprec: The tolerance used when determining the symmetry of the structure. The symmetry can used both to determine if multiple sites are symmetrically equivalent and to obtain the symmetry labels for each site. minimum_geometry_op: The minimum geometrical order parameter for a geometry match to be returned. use_iupac_formula (bool, optional): Whether to order formulas by the iupac "electronegativity" series, defined in Table VI of "Nomenclature of Inorganic Chemistry (IUPAC Recommendations 2005)". This ordering effectively follows the groups and rows of the periodic table, except the Lanthanides, Actanides and hydrogen. If set to ``False``, the elements will be ordered according to the electronegativity values. """ def __init__( self, bonded_structure: StructureGraph, use_symmetry_equivalent_sites: bool = False, symprec: float = 0.01, minimum_geometry_op: float = 0.4, use_iupac_formula: bool = True, ): self.bonded_structure = bonded_structure self.use_iupac_formula = use_iupac_formula self.minimum_geometry_op = minimum_geometry_op self.site_fingerprints = get_site_fingerprints(bonded_structure.structure) sga = SpacegroupAnalyzer(bonded_structure.structure, symprec=symprec) equivalent_sites = sga.get_symmetry_dataset().equivalent_atoms if use_symmetry_equivalent_sites: self.equivalent_sites = list(equivalent_sites) else: self.equivalent_sites = self._calculate_equivalent_sites() self.symmetry_labels = self._calculate_symmetry_labels( equivalent_sites.tolist() ) ``` -------------------------------- ### Main Execution Logic Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/cli.html Parses CLI arguments, filters warnings, and initializes structure retrieval from files or the Materials Project API. ```python [docs] def main(): args = _get_parser().parse_args() args_dict = vars(args) condenser_keys = [ "use_conventional_cell", "use_symmetry_equivalent_sites", "symprec", "use_iupac_formula", "use_common_formulas", ] describer_keys = [ "describe_mineral", "describe_component_makeup", "describe_components", "describe_symmetry_labels", "describe_oxidation_states", "describe_bond_lengths", "bond_length_decimal_places", "distorted_tol", "only_describe_cation_polyhedra_connectivity", "only_describe_bonds_once", "fmt", ] condenser_kwargs = {key: args_dict[key] for key in condenser_keys} describer_kwargs = {key: args_dict[key] for key in describer_keys} warnings.filterwarnings("ignore", category=UserWarning, module="pymatgen") warnings.filterwarnings("ignore", category=DeprecationWarning) try: structure = Structure.from_file(args.filename) except FileNotFoundError: if args.filename[:3] in ["mp-", "mvc"]: if MPRestError is None: raise ImportError( "Please install the Materials Project API using" "`pip install mp_api`" ) from mp_api.client import MPRester mpr = MPRester(args.api_key) ``` -------------------------------- ### MineralMatcher Class Initialization Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/mineral.html Initializes the matcher with specific tolerances and database configuration. ```python def __init__( self, initial_ltol: float = 0.2, initial_stol: float = 0.3, initial_angle_tol: float = 5.0, use_fingerprint_matching: bool = True, fingerprint_distance_cutoff: float = 0.4, mineral_db: str | Path | pd.DataFrame | None = None, ): mineral_db = mineral_db or _mineral_db_file if isinstance(mineral_db, (str, Path)): self.mineral_db = load_mineral_db_file(mineral_db) else: self.mineral_db = mineral_db self.initial_ltol = initial_ltol self.initial_stol = initial_stol self.initial_angle_tol = initial_angle_tol self.fingerprint_distance_cutoff = fingerprint_distance_cutoff self.use_fingerprint_matching = use_fingerprint_matching self._structure: Structure | None = None self._mineral_db: pd.DataFrame | None = None ``` -------------------------------- ### Get Symmetrically Inequivalent Components Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/component.html Identifies and counts components that are symmetrically inequivalent using a SpacegroupAnalyzer. ```python def get_sym_inequiv_components( components: list[Component], spg_analyzer: SpacegroupAnalyzer ) -> list[Component]: """Gets and counts the symmetrically inequivalent components. Component data has to have been generated with ``inc_site_ids=True``. Args: components: A list of structure components, generated using :obj:`pymatgen.analysis.dimensionality.get_structure_components`, with ``inc_site_ids=True``. spg_analyzer: A `pymatgen.symmetry.analyzer.SpacegroupAnalyzer` analyzer object for the structure containing the components. Returns: A list of the symmetrically inequivalent components. Any duplicate components will only be returned once. The component objects are in the same format is given by :obj:`pymatgen.analysis.dimensionality.get_structure_components` but the additional property: - ``"count"`` (:obj:`int`): The number of times this component appears in the structure. """ components = deepcopy(components) sym_inequiv_components: dict[frozenset, Component] = {} equivalent_atoms = spg_analyzer.get_symmetry_dataset().equivalent_atoms for component in components: sym_indices = frozenset(equivalent_atoms[x] for x in component["site_ids"]) # if two components are composed of atoms that are symmetrically # equivalent they are the same. if sym_indices in sym_inequiv_components: sym_inequiv_components[sym_indices]["count"] += 1 continue component["count"] = 1 sym_inequiv_components[sym_indices] = component return list(sym_inequiv_components.values()) ``` -------------------------------- ### StructureCondenser.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/condenser.html Initializes the StructureCondenser with configuration for neighbor analysis, mineral matching, and symmetry handling. ```APIDOC ## Constructor: StructureCondenser(use_conventional_cell=True, near_neighbors=None, mineral_matcher=None, use_symmetry_equivalent_sites=False, symprec=0.01, simplify_molecules=True, use_iupac_formula=True, use_common_formulas=True) ### Description Initializes a new instance of the StructureCondenser class. ### Parameters - **use_conventional_cell** (bool) - Optional - Whether to always use the conventional cell representation. - **near_neighbors** (NearNeighbors) - Optional - A NearNeighbors instance for bonding calculations. - **mineral_matcher** (MineralMatcher) - Optional - A MineralMatcher instance for mineral identification. - **use_symmetry_equivalent_sites** (bool) - Optional - Whether to use symmetry to determine if sites are inequivalent. - **symprec** (float) - Optional - Tolerance for symmetry determination. - **simplify_molecules** (bool) - Optional - Whether to simplify molecular components. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by IUPAC electronegativity series. - **use_common_formulas** (bool) - Optional - Whether to use a database of common formulas. ``` -------------------------------- ### Initialize command-line parser Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/cli.html Creates an argparse parser configured for the robocrystallographer tool. ```python def _get_parser(): parser = argparse.ArgumentParser( description="robocrystallographer is a tool to generate crystal " "structure descriptions", epilog="Author: {}, Version: {}, Last updated: {}".format( __author__, __version__, __date__ ), ) ``` -------------------------------- ### Display robocrys usage information Source: https://hackingmaterials.lbl.gov/robocrystallographer/cli.html View the command-line interface help and available arguments for the robocrys tool. ```bash usage: robocrys [-h] [-c] [-s] [--symprec SYMPREC] [--no-simplify] [--no-iupac] [--no-common-formulas] [--no-mineral] [--no-makeup] [--no-components] [--no-symmetry-labels] [--no-oxi] [--no-bond] [--precision P] [--distorted-tol T] [--anion-polyhedra] [--verbose-bonds] [--format FMT] [--api-key API_KEY] filename ``` -------------------------------- ### Get inequivalent site indices Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Maps a list of site indices to their corresponding inequivalent site indices. ```python [0, 0, 2, 3] ``` -------------------------------- ### StructureCondenser.__init__ Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Initializes the StructureCondenser with configuration parameters for structure analysis. ```APIDOC ## Class: StructureCondenser ### Description Initializes a new instance of the StructureCondenser to transform a structure into an intermediate dict representation. ### Parameters - **use_conventional_cell** (bool) - Optional - Whether to always use the conventional cell representation. - **near_neighbors** (NearNeighbors | None) - Optional - Instance used to calculate bonding (e.g., CrystalNN). - **mineral_matcher** (MineralMatcher | None) - Optional - Instance for mineral matching. - **use_symmetry_equivalent_sites** (bool) - Optional - Whether to use symmetry to determine if sites are inequivalent. - **symprec** (float) - Optional - Tolerance for symmetry determination. - **use_iupac_formula** (bool) - Optional - Whether to order formulas by IUPAC electronegativity series. - **use_common_formulas** (bool) - Optional - Whether to use the database of common formulas. ``` -------------------------------- ### MineralMatcher Source: https://hackingmaterials.lbl.gov/robocrystallographer/robocrys.condense.html Initializes the MineralMatcher with specific tolerances and database configurations for structure matching. ```APIDOC ## MineralMatcher(initial_ltol=0.2, initial_stol=0.3, initial_angle_tol=5.0, use_fingerprint_matching=True, fingerprint_distance_cutoff=0.4, mineral_db=None) ### Description Initializes a new instance of the MineralMatcher class to match structures to known mineral names using AFLOW prototypes. ### Parameters - **initial_ltol** (float) - Optional - The fractional length tolerance. - **initial_stol** (float) - Optional - The site coordinate tolerance. - **initial_angle_tol** (float) - Optional - The angle tolerance. - **use_fingerprint_matching** (bool) - Optional - Whether to use fingerprint distance for matching. - **fingerprint_distance_cutoff** (float) - Optional - Cutoff distance for fingerprint matching. - **mineral_db** (str | Path | DataFrame | None) - Optional - Path or DataFrame containing the mineral fingerprint database. ``` -------------------------------- ### Get Site Geometry Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/site.html Retrieves the bonding geometry type and order parameter for a specific site index. ```python def get_site_geometry(self, site_index: int) -> dict[str, str | float]: """Gets the bonding geometry of a site. For example, "octahedral" or "square-planar". Args: site_index: The site index (zero based). Returns: The site geometry information formatted at as:: {'type': geometry_type, 'likeness': order_parameter} Where ``geometry_type`` is a :obj:`str` corresponding to the geometry type (e.g. octahedral) and ``order_parameter`` is a :obj:`float` indicating whether how close the geometry is to the perfect geometry. If the largest geometrical order parameter falls beneath :attr:`robocrys.site.SiteAnalyzer.minimum_geometry_op`, the geometry type will be returned as "X-coordinate", where X is the coordination number. """ # get fingerprint as a list of tuples, e.g. [("op name", val), ...] site_fingerprint: list[tuple[str, int]] = list( self.site_fingerprints[site_index].items() ) ``` -------------------------------- ### Get Best Mineral Name Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/condense/mineral.html Retrieves the best matching mineral name for a given pymatgen Structure object. ```python def get_best_mineral_name(self, structure: Structure) -> dict[str, Any]: """Gets the "best" mineral name for a structure. Uses a combination of AFLOW prototype matching and fingerprinting to get the best mineral name. The AFLOW structure prototypes are detailed in reference [aflow]_. The algorithm works as follows: 1. Check for AFLOW match. If single match return mineral name. 2. If multiple matches, return the one with the smallest fingerprint distance. 3. If no AFLOW match, get fingerprints within tolerance. If there are any matches, take the one with the smallest distance. 4. If no fingerprints within tolerance, check get fingerprints without constraining the number of species types. If any matches, take the best one. Args: structure (Structure): A pymatgen ``Structure`` object to match. ``` -------------------------------- ### Initialize and Use RobocrysFeaturizer Source: https://hackingmaterials.lbl.gov/robocrystallographer/_modules/robocrys/featurize/featurizer.html The RobocrysFeaturizer class is initialized with optional condenser arguments and a distortion tolerance. The featurize method processes a pymatgen Structure to return a list of features. ```python class RobocrysFeaturizer(BaseFeaturizer): """Class to generate structure features from robocrystallographer output. Args: condenser_kwargs: Keyword arguments that will be passed to :obj:`robocrys.condense.StructureCondenser`. distorted_tol: The value under which the site geometry will be classified as distorted. """ def __init__( self, condenser_kwargs: dict | None = None, distorted_tol: float = 0.6 ): condenser_kwargs = condenser_kwargs if condenser_kwargs else {} self._sc = StructureCondenser(**condenser_kwargs) self._distorted_tol = distorted_tol def featurize(self, s: Structure) -> list[float | bool | str | None]: """Featurizes a structure using robocrystallographer. Args: s: A structure. Returns: The robocrystallographer features. """ fa = FeaturizerAdapter( self._sc.condense_structure(s), distorted_tol=self._distorted_tol ) # add general structure features features: list[float | bool | str | None] = [ fa.mineral["type"], fa.spg_symbol, fa.crystal_system, fa.dimensionality, fa.is_vdw_heterostructure, fa.is_interpenetrated, fa.is_intercalated, ] # add dimensionality features features += [fa.is_dimensionality(d) for d in _dimensionalities] features += [fa.is_dimensionality(d) for d in _dimensionality_sets] features += [d in fa.component_dimensionalities for d in _dimensionalities] # add molecule features features += [fa.contains_named_molecule] features += [fa.contains_molecule(m) for m in _molecules] # add geometry features features += [fa.contains_geometry_type(g) for g in _geometries] features += [fa.contains_geometry_type(g, distorted=True) for g in _geometries] features += [ fa.average_coordination_number, fa.average_cation_coordination_number, fa.average_anion_coordination_number, ] # add polyhedral features features += [ fa.contains_polyhedra, fa.contains_corner_sharing_polyhedra, fa.contains_edge_sharing_polyhedra, fa.contains_face_sharing_polyhedra, ] # add connectivity features features += [ fa.contains_connected_geometry(c, g) for c, g in product(_connectivities, connected_geometries) ] features += [fa.average_corner_sharing_octahedral_tilt_angle] # add fractional features features += [fa.frac_sites_polyhedra] features += [fa.frac_site_geometry(g) for g in _geometries] features += [fa.frac_sites_n_coordinate(n) for n in _cns] all_distances = fa.all_bond_lengths() # add bond length features features += [max(all_distances), min(all_distances), mean(all_distances)] return features def feature_labels(self): # general features labels = [ "mineral_prototype", "spg_symbol", "crystal_system", "dimensionality", "is_vdw_heterostructure", "is_interpenetrated", "is_intercalated", ] # dimensionality features labels += [f"is_only_{d}d" for d in _dimensionalities] labels += [ "is_{}".format("_".join([f"{d}d" for d in ds])) for ds in _dimensionality_sets ] labels += [f"contains_{d}d_component" for d in _dimensionalities] # molecule features labels += ["contains_named_molecule"] labels += [f"contains_{m}" for m in _molecules] ```