Exemple #1
0
    def test_substitute(self):
        structure = Structure.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "Li2O.cif"))
        molecule = FunctionalGroups["methyl"]

        structure_copy = copy.deepcopy(structure)
        structure_copy_graph = copy.deepcopy(structure)

        sg = StructureGraph.with_local_env_strategy(structure, MinimumDistanceNN())
        sg_copy = copy.deepcopy(sg)

        # Ensure that strings and molecules lead to equivalent substitutions
        sg.substitute_group(1, molecule, MinimumDistanceNN)
        sg_copy.substitute_group(1, "methyl", MinimumDistanceNN)
        self.assertEqual(sg, sg_copy)

        # Ensure that the underlying structure has been modified as expected
        structure_copy.substitute(1, "methyl")
        self.assertEqual(structure_copy, sg.structure)

        # Test inclusion of graph dictionary
        graph_dict = {
            (0, 1): {"weight": 0.5},
            (0, 2): {"weight": 0.5},
            (0, 3): {"weight": 0.5},
        }

        sg_with_graph = StructureGraph.with_local_env_strategy(structure_copy_graph, MinimumDistanceNN())
        sg_with_graph.substitute_group(1, "methyl", MinimumDistanceNN, graph_dict=graph_dict)
        edge = sg_with_graph.graph.get_edge_data(11, 13)[0]
        self.assertEqual(edge["weight"], 0.5)
Exemple #2
0
    def test_mul(self):

        square_sg_mul = self.square_sg * (2, 1, 1)

        square_sg_mul_ref_str = """Structure Graph
Structure:
Full Formula (H2)
Reduced Formula: H2
abc   :  10.000000   5.000000  50.000000
angles:  90.000000  90.000000  90.000000
Sites (2)
  #  SP      a    b    c
---  ----  ---  ---  ---
  0  H     0      0    0
  1  H     0.5    0   -0
Graph: bonds
from    to  to_image
----  ----  ------------
   0     0  (0, 1, 0)
   0     0  (0, -1, 0)
   0     1  (0, 0, 0)
   0     1  (-1, 0, 0)
   1     1  (0, 1, 0)
   1     1  (0, -1, 0)
"""
        square_sg_mul_actual_str = str(square_sg_mul)

        # only testing bonds portion,
        # the c frac_coord of the second H can vary from
        # 0 to -0 depending on machine precision
        square_sg_mul_ref_str = "\n".join(square_sg_mul_ref_str.splitlines()[11:])
        square_sg_mul_actual_str = "\n".join(square_sg_mul_actual_str.splitlines()[11:])

        self.assertStrContentEqual(square_sg_mul_actual_str, square_sg_mul_ref_str)

        # test sequential multiplication
        sq_sg_1 = self.square_sg * (2, 2, 1)
        sq_sg_1 = sq_sg_1 * (2, 2, 1)
        sq_sg_2 = self.square_sg * (4, 4, 1)
        self.assertEqual(sq_sg_1.graph.number_of_edges(), sq_sg_2.graph.number_of_edges())
        # TODO: the below test still gives 8 != 4
        # self.assertEqual(self.square_sg.get_coordination_of_site(0), 4)

        mos2_sg_mul = self.mos2_sg * (3, 3, 1)
        for idx in mos2_sg_mul.structure.indices_from_symbol("Mo"):
            self.assertEqual(mos2_sg_mul.get_coordination_of_site(idx), 6)

        mos2_sg_premul = StructureGraph.with_local_env_strategy(self.structure * (3, 3, 1), MinimumDistanceNN())
        self.assertTrue(mos2_sg_mul == mos2_sg_premul)

        # test 3D Structure

        nio_sg = StructureGraph.with_local_env_strategy(self.NiO, MinimumDistanceNN())
        nio_sg = nio_sg * 3

        for n in range(len(nio_sg)):
            self.assertEqual(nio_sg.get_coordination_of_site(n), 6)
Exemple #3
0
    def get_bonds(self):
        graph = StructureGraph.with_local_env_strategy(
            self.structure, CutOffDictNN({("Si", "O"): 2.0, ("O", "Si"): 2.0})
        )

        # GULP starts counting on 1
        return [(u + 1, v + 1, "single") for u, v in graph.graph.edges()]
Exemple #4
0
 def _has_stray_molecules(self) -> bool:
     self._set_cnn()
     sgraph = StructureGraph.with_local_env_strategy(self.structure, self._cnn)
     molecules = get_subgraphs_as_molecules_all(sgraph)
     if len(molecules) > 0:
         return True
     return False
def subgraph_translate3(read_path, write_dir):
    '''
    This function takes the metal-deficient structure and saves the all connected components (i.e. linkers)
    '''
    ase_struct = read(read_path)
    struct = pm.get_structure(ase_struct)
    n_atoms = len(struct.sites)
    sg = StructureGraph.with_local_env_strategy(struct, env.JmolNN(tol=.3))
    count = 1
    for i in range(n_atoms):
        for j in range(n_atoms):
            if i != j:
                try:
                    sg.alter_edge(i, j, new_weight=count)
                except:
                    pass
                count += 1

    A = sg.get_subgraphs_as_molecules(use_weights=True)

    ls = []
    count = 0
    for mol in A:
        if len(mol.sites) > 4:
            smiles = getSmiles(mol)
            ls.append(smiles)
            path = write_dir + 'mol_' + str(count) + '.xyz'
            saveMol(mol, path)
            count += 1
    return count, ls
Exemple #6
0
    def test_no_duplicate_hops(self):

        test_structure_dict = {
            "@module":
            "pymatgen.core.structure",
            "@class":
            "Structure",
            "charge":
            None,
            "lattice": {
                "matrix": [[2.990355, -5.149042, 0.0],
                           [2.990355, 5.149042, 0.0], [0.0, 0.0, 24.51998]]
            },
            "sites": [
                {
                    "species": [{
                        "element": "Ba",
                        "occu": 1
                    }],
                    "abc": [0.005572, 0.994428, 0.151095],
                    "properties": {}
                },
            ],
        }

        test_structure = Structure.from_dict(test_structure_dict)

        nn = MinimumDistanceNN(cutoff=6, get_all_sites=True)

        sg = StructureGraph.with_local_env_strategy(test_structure, nn)

        self.assertEqual(sg.graph.number_of_edges(), 3)
    def __init__(self,
                 structure,
                 migrating_specie,
                 max_path_length=10,
                 symprec=0.1,
                 vac_mode=False):
        """
        Args:
            structure: Input structure that contains all sites.
            migrating_specie (Specie-like): The specie that migrates. E.g.,
                "Li".
            max_path_length (float): Maximum length of NEB path in the unit
                of Angstrom. Defaults to None, which means you are setting the
                value to the min cutoff until finding 1D or >1D percolating paths.
            symprec (float): Symmetry precision to determine equivalence.
        """
        self.structure = structure
        self.migrating_specie = get_el_sp(migrating_specie)
        self.symprec = symprec
        self.a = SpacegroupAnalyzer(self.structure, symprec=self.symprec)
        self.symm_structure = self.a.get_symmetrized_structure()
        self.only_sites = self.get_only_sites()
        self.unique_hops = None

        # Generate the graph edges between these all the sites
        self.s_graph = StructureGraph.with_local_env_strategy(
            self.only_sites,
            MinimumDistanceNN(
                cutoff=max_path_length,
                get_all_sites=True))  # weights in this graph are the distances
        self.s_graph.set_node_attributes()
Exemple #8
0
    def _get_graphs(cutoff, ordered_structures):
        """
        Generate graph representations of magnetic structures with nearest
        neighbor bonds. Right now this only works for MinimumDistanceNN.

        Args:
            cutoff (float): Cutoff in Angstrom for nearest neighbor search.
            ordered_structures (list): Structure objects.

        Returns:
            sgraphs (list): StructureGraph objects.

        """

        # Strategy for finding neighbors
        if cutoff:
            strategy = MinimumDistanceNN(cutoff=cutoff, get_all_sites=True)
        else:
            strategy = MinimumDistanceNN()  # only NN

        # Generate structure graphs
        sgraphs = [
            StructureGraph.with_local_env_strategy(s, strategy=strategy)
            for s in ordered_structures
        ]

        return sgraphs
Exemple #9
0
    def _preprocess_input_to_graph(
        input: Union[Structure, StructureGraph, Molecule, MoleculeGraph],
        bonding_strategy: str = "CrystalNN",
        bonding_strategy_kwargs: Optional[Dict] = None,
    ) -> Union[StructureGraph, MoleculeGraph]:

        if isinstance(input, Structure):

            # ensure fractional co-ordinates are normalized to be in [0,1)
            # (this is actually not guaranteed by Structure)
            input = input.as_dict(verbosity=0)
            for site in input["sites"]:
                site["abc"] = np.mod(site["abc"], 1)
            input = Structure.from_dict(input)

            if not input.is_ordered:
                # calculating bonds in disordered structures is currently very flaky
                bonding_strategy = "CutOffDictNN"

        # we assume most uses of this class will give a structure as an input argument,
        # meaning we have to calculate the graph for bonding information, however if
        # the graph is already known and supplied, we will use that
        if isinstance(input, StructureGraph) or isinstance(
                input, MoleculeGraph):
            graph = input
        else:
            if (bonding_strategy not in StructureMoleculeComponent.
                    available_bonding_strategies.keys()):
                raise ValueError(
                    "Bonding strategy not supported. Please supply a name "
                    "of a NearNeighbor subclass, choose from: {}".format(
                        ", ".join(StructureMoleculeComponent.
                                  available_bonding_strategies.keys())))
            else:
                bonding_strategy_kwargs = bonding_strategy_kwargs or {}
                if bonding_strategy == "CutOffDictNN":
                    if "cut_off_dict" in bonding_strategy_kwargs:
                        # TODO: remove this hack by making args properly JSON serializable
                        bonding_strategy_kwargs["cut_off_dict"] = {
                            (x[0], x[1]): x[2]
                            for x in bonding_strategy_kwargs["cut_off_dict"]
                        }
                bonding_strategy = StructureMoleculeComponent.available_bonding_strategies[
                    bonding_strategy](**bonding_strategy_kwargs)
                try:
                    if isinstance(input, Structure):
                        graph = StructureGraph.with_local_env_strategy(
                            input, bonding_strategy)
                    else:
                        graph = MoleculeGraph.with_local_env_strategy(
                            input, bonding_strategy)
                except:
                    # for some reason computing bonds failed, so let's not have any bonds(!)
                    if isinstance(input, Structure):
                        graph = StructureGraph.with_empty_graph(input)
                    else:
                        graph = MoleculeGraph.with_empty_graph(input)

        return graph
Exemple #10
0
    def test_from_local_env_and_equality_and_diff(self):
        nn = MinimumDistanceNN()
        sg = StructureGraph.with_local_env_strategy(self.structure, nn)

        self.assertEqual(sg.graph.number_of_edges(), 6)

        nn2 = MinimumOKeeffeNN()
        sg2 = StructureGraph.with_local_env_strategy(self.structure, nn2)

        self.assertTrue(sg == sg2)
        self.assertTrue(sg == self.mos2_sg)

        # TODO: find better test case where graphs are different
        diff = sg.diff(sg2)
        self.assertEqual(diff["dist"], 0)

        self.assertEqual(self.square_sg.get_coordination_of_site(0), 2)
Exemple #11
0
 def _has_lone_atom(self):
     self._set_cnn()
     graph = StructureGraph.with_local_env_strategy(self.structure, self._cnn)
     for site in range(len(self.structure)):
         nbr = graph.get_connected_sites(site)
         if not nbr:
             return True
     return False
 def compare_graph_pair_cached(self, items):
     nn_strategy = JmolNN()
     crystal_a = self.reduced_structure_dict[
         self.scalar_feature_matrix.iloc[items[0]]["name"]]
     crystal_b = self.reduced_structure_dict[
         self.scalar_feature_matrix.iloc[items[1]]["name"]]
     if self.try_supercell:
         crystal_a, crystal_b = attempt_supercell_pymatgen(
             crystal_a, crystal_b)
     sgraph_a = StructureGraph.with_local_env_strategy(
         crystal_a, nn_strategy)
     sgraph_b = StructureGraph.with_local_env_strategy(
         crystal_b, nn_strategy)
     try:
         if sgraph_a == sgraph_b:
             logger.debug("Found duplicate")
             return items
     except ValueError:
         logger.debug("Structures were probably not different")
         return False
Exemple #13
0
def get_cooccurrence_pairs(struct):
    pairs = []
    struct_graph = StructureGraph.with_local_env_strategy(struct, CrystalNN())
    labels = {i: spec.name for i, spec in enumerate(struct.species)}
    G = struct_graph.graph.to_undirected()
    for n in labels:
        target = labels[n]
        # TODO what if the atom doesn't have any neighbors?
        neighbors = [labels[i] for i in G.neighbors(n)]
        for neighbor in neighbors:
            pairs.append((target, neighbor))
    return pairs
Exemple #14
0
    def test_no_duplicate_hops(self):

        test_structure = Structure(
            lattice=[[2.990355, -5.149042, 0.0], [2.990355, 5.149042, 0.0], [0.0, 0.0, 24.51998]],
            species=["Ba"],
            coords=[[0.005572, 0.994428, 0.151095]],
        )

        nn = MinimumDistanceNN(cutoff=6, get_all_sites=True)

        sg = StructureGraph.with_local_env_strategy(test_structure, nn)

        self.assertEqual(sg.graph.number_of_edges(), 3)
Exemple #15
0
 def count_cooccurrences_single(struct):
     counts = {}
     struct_graph = StructureGraph.with_local_env_strategy(struct, CrystalNN())
     labels = {i: spec.name for i, spec in enumerate(struct.species)}
     G = struct_graph.graph.to_undirected()
     for n in labels:
         target = labels[n]
         neighbors = [labels[i] for i in G.neighbors(n)]
         for neighbor in neighbors:
             key = frozenset([target, neighbor])
             if key not in counts:
                 counts[key] = 0
             counts[key] += 1
     return counts
Exemple #16
0
 def _has_undercoordinated_nitrogen(self, tolerance=10):
     """
     Captures missing hydrogens on amino groups.
     Basically two common cases:
         1. Have the N on a carbon and no hydrogen at all
         2. (not that common) due to incorrect symmetry resolution
             we have only one h in a bent orientation
     """
     undercoordinated_nitrogen = False
     for site_index in self.n_indices:
         cn = self.get_cn(site_index)  # pylint:disable=invalid-name
         if cn == 1:
             # this is suspicous, but it also might a CN wish is perfectly fine
             # to check this, we first see if the neighbor is carbon
             # and then what its coordination number is
             graph = StructureGraph.with_local_env_strategy(
                 self.structure, self._cnn
             )
             neighbors = graph.get_connected_sites(site_index)
             if (self.get_cn(neighbors[0].index) > 2) and (
                 str(neighbors[0].periodic_site.specie) == "C"
             ):
                 undercoordinated_nitrogen = True
                 break
         if cn == 2:
             # ToDo: Check if it is bound to metal, then it might be a nitride
             graph = StructureGraph.with_local_env_strategy(
                 self.structure, self._cnn
             )
             neighbors = graph.get_connected_sites(site_index)
             angle = self.structure.get_angle(
                 site_index, neighbors[0].index, neighbors[1].index
             )
             if np.abs(90 - angle) > tolerance:
                 undercoordinated_nitrogen = True
                 break
     self._undercoordinated_nitrogen = undercoordinated_nitrogen
    def _preprocess_input_to_graph(
        input: Union[Structure, StructureGraph],
        bonding_strategy: str = DEFAULTS["bonding_strategy"],
        bonding_strategy_kwargs: Optional[Dict] = None,
    ) -> Union[StructureGraph, MoleculeGraph]:

        # ensure fractional co-ordinates are normalized to be in [0,1)
        # (this is actually not guaranteed by Structure)
        try:
            input = input.as_dict(verbosity=0)
        except TypeError:
            # TODO: remove this, necessary for Slab(?), some structure subclasses don't have verbosity
            input = input.as_dict()
        for site in input["sites"]:
            site["abc"] = np.mod(site["abc"], 1)
        input = Structure.from_dict(input)

        if not input.is_ordered:
            # calculating bonds in disordered structures is currently very flaky
            bonding_strategy = "CutOffDictNN"

        if (bonding_strategy
                not in StructureComponent.available_bonding_strategies.keys()):
            raise ValueError(
                "Bonding strategy not supported. Please supply a name "
                "of a NearNeighbor subclass, choose from: {}".format(", ".join(
                    StructureComponent.available_bonding_strategies.keys())))
        else:
            bonding_strategy_kwargs = bonding_strategy_kwargs or {}
            if bonding_strategy == "CutOffDictNN":
                if "cut_off_dict" in bonding_strategy_kwargs:
                    # TODO: remove this hack by making args properly JSON serializable
                    bonding_strategy_kwargs["cut_off_dict"] = {
                        (x[0], x[1]): x[2]
                        for x in bonding_strategy_kwargs["cut_off_dict"]
                    }
            bonding_strategy = StructureComponent.available_bonding_strategies[
                bonding_strategy](**bonding_strategy_kwargs)
            try:
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore")
                    graph = StructureGraph.with_local_env_strategy(
                        input, bonding_strategy)
            except:
                # for some reason computing bonds failed, so let's not have any bonds(!)
                graph = StructureGraph.with_empty_graph(input)

        return graph
 def with_local_env_strategy(cls, structure: Structure,
                             migrating_specie: str, nn: NearNeighbors,
                             **kwargs) -> "MigrationGraph":
     """
     Using a specific nn strategy to get the connectivity graph between all the migrating ion sites.
     Args:
         structure: Input structure that contains all sites.
         migrating_specie: The specie that migrates. E.g. "Li".
         nn: The specific local environment object used to connect the migrating ion sites.
     Returns:
         A constructed MigrationGraph object
     """
     only_sites = get_only_sites_from_structure(structure, migrating_specie)
     migration_graph = StructureGraph.with_local_env_strategy(
         only_sites, nn)
     return cls(structure=structure, m_graph=migration_graph, **kwargs)
Exemple #19
0
def get_mol_pymatgen(dataframe, nbrStruc):
    
    for i in range(nbrStruc):
        filename = dataframe.iloc[i,0]
        if (filename != "QAPHUK"):
            print(filename)
            parser = CifParser("../data/cif/{}.cif".format(filename))
            structure = parser.get_structures()[0]
            sg = StructureGraph.with_local_env_strategy(structure, locenv.JmolNN())
            my_molecules = sg.get_subgraphs_as_molecules()
            #molecule = MoleculeGraph.with_local_env_strategy(my_molecules,locenv.JmolNN())
            #print(molecule)
            #crystool.view(my_molecules)
            my_molecules = pyxyz.XYZ(my_molecules)
            #print(my_molecules)
            pyxyz.XYZ.write_file(my_molecules,"../data/xyz_pymatgen/{}.xyz".format(filename))
 def with_distance(cls, structure: Structure, migrating_specie: str,
                   max_distance: float, **kwargs) -> "MigrationGraph":
     """
     Using a specific nn strategy to get the connectivity graph between all the migrating ion sites.
     Args:
         max_distance: Maximum length of NEB path in the unit
             of Angstrom. Defaults to None, which means you are setting the
             value to the min cutoff until finding 1D or >1D percolating paths.
     Returns:
         A constructed MigrationGraph object
     """
     only_sites = get_only_sites_from_structure(structure, migrating_specie)
     migration_graph = StructureGraph.with_local_env_strategy(
         only_sites,
         MinimumDistanceNN(cutoff=max_distance, get_all_sites=True),
     )
     return cls(structure=structure, m_graph=migration_graph, **kwargs)
Exemple #21
0
def get_local_environment(
        structure: Structure, n: int, loc_env_strategy: NearNeighbors
) -> List[Molecule]:
    """Create the molecule object of the local environment
    based on a given local environment strategy

    Args:
        structure (Structure): Input structure
        n (int): The site index
        loc_env_strategy (NearNeighbors):

    Returns:
        Molecule: [description]
    """

    s_graph = StructureGraph.with_local_env_strategy(loc_env_strategy)
    return s_graph.get_subgraphs_as_molecules()
Exemple #22
0
    def test_draw(self):

        # draw MoS2 graph
        self.mos2_sg.draw_graph_to_file("MoS2_single.pdf", image_labels=True, hide_image_edges=False)
        mos2_sg = self.mos2_sg * (9, 9, 1)
        mos2_sg.draw_graph_to_file("MoS2.pdf", algo="neato")

        # draw MoS2 graph that's been successively multiplied
        mos2_sg_2 = self.mos2_sg * (3, 3, 1)
        mos2_sg_2 = mos2_sg_2 * (3, 3, 1)
        mos2_sg_2.draw_graph_to_file("MoS2_twice_mul.pdf", algo="neato", hide_image_edges=True)

        # draw MoS2 graph that's generated from a pre-multiplied Structure
        mos2_sg_premul = StructureGraph.with_local_env_strategy(self.structure * (3, 3, 1), MinimumDistanceNN())
        mos2_sg_premul.draw_graph_to_file("MoS2_premul.pdf", algo="neato", hide_image_edges=True)

        # draw graph for a square lattice
        self.square_sg.draw_graph_to_file("square_single.pdf", hide_image_edges=False)
        square_sg = self.square_sg * (5, 5, 1)
        square_sg.draw_graph_to_file("square.pdf", algo="neato", image_labels=True, node_labels=False)

        # draw graph for a body-centered square lattice
        self.bc_square_sg.draw_graph_to_file("bc_square_single.pdf", hide_image_edges=False)
        bc_square_sg = self.bc_square_sg * (9, 9, 1)
        bc_square_sg.draw_graph_to_file("bc_square.pdf", algo="neato", image_labels=False)

        # draw graph for a body-centered square lattice defined in an alternative way
        self.bc_square_sg_r.draw_graph_to_file("bc_square_r_single.pdf", hide_image_edges=False)
        bc_square_sg_r = self.bc_square_sg_r * (9, 9, 1)
        bc_square_sg_r.draw_graph_to_file("bc_square_r.pdf", algo="neato", image_labels=False)

        # delete generated test files
        test_files = (
            "bc_square_r_single.pdf",
            "bc_square_r.pdf",
            "bc_square_single.pdf",
            "bc_square.pdf",
            "MoS2_premul.pdf",
            "MoS2_single.pdf",
            "MoS2_twice_mul.pdf",
            "MoS2.pdf",
            "square_single.pdf",
            "square.pdf",
        )
        for test_file in test_files:
            os.remove(test_file)
Exemple #23
0
    def __init__(
        self,
        structure,
        migrating_specie,
        max_path_length=10,
        symprec=0.1,
        vac_mode=False,
        name: str = None,
    ):
        """
        Construct the FullPathMapper object using a structure will all mobile sites occupied.
        A structure graph is generated by connecting all sites withing max_path_length distance of each other
        The sites are decorated with Migration graph objects and then grouped together based on their equivalence.

        Args:
            structure: Input structure that contains all sites.
            migrating_specie (Specie-like): The specie that migrates. E.g.,
                "Li".
            max_path_length (float): Maximum length of NEB path in the unit
                of Angstrom. Defaults to None, which means you are setting the
                value to the min cutoff until finding 1D or >1D percolating paths.
            symprec (float): Symmetry precision to determine equivalence.
        """
        self.structure = structure
        self.migrating_specie = get_el_sp(migrating_specie)
        self.max_path_length = max_path_length
        self.symprec = symprec
        self.name = name
        self.a = SpacegroupAnalyzer(self.structure, symprec=self.symprec)
        self.symm_structure = self.a.get_symmetrized_structure()
        self.only_sites = self.get_only_sites()
        if vac_mode:
            raise NotImplementedError
        self.vac_mode = vac_mode
        self.unique_hops = None

        # Generate the graph edges between these all the sites
        self.s_graph = StructureGraph.with_local_env_strategy(
            self.only_sites,
            MinimumDistanceNN(cutoff=max_path_length, get_all_sites=True),
        )  # weights in this graph are the distances
        self.s_graph.set_node_attributes()
        self.populate_edges_with_migration_paths()
        self.group_and_label_hops()
        self._populate_unique_hops_dict()
Exemple #24
0
    def compute_graph(self, index, cached=False, method="jmolnn"):
        if cached:
            s = self.reduced_structure_dict[
                self.scalar_feature_matrix.iloc[index]["name"]]
        else:
            s = Structure.from_file(
                self.scalar_feature_matrix.iloc[index]["name"])

        if method == "jmolnn":
            nn_strategy = JmolNN()
        elif method == "crystalgraph":
            nn_strategy = CrystalNN()
        else:
            nn_strategy = JmolNN()

        graph = StructureGraph.with_local_env_strategy(s, nn_strategy)

        return graph
    def walk(struct, p, q, num_walks, walk_length):
        struct_graph = StructureGraph.with_local_env_strategy(
            struct, CrystalNN())
        labels = {i: spec.name for i, spec in enumerate(struct.species)}
        G = nx.Graph(struct_graph.graph)
        G = nx.relabel_nodes(G, labels)

        for source, target in G.edges():
            G[source][target]['weight'] = 1

        n2v_G = Node2VecGraph(G, is_directed=False, p=p, q=q)

        n2v_G.preprocess_transition_probs()
        walks = n2v_G.simulate_walks(num_walks=num_walks,
                                     walk_length=walk_length,
                                     verbose=False)

        return walks
Exemple #26
0
    def test_extract_molecules(self):

        structure_file = os.path.join(
            PymatgenTest.TEST_FILES_DIR,
            "H6PbCI3N_mp-977013_symmetrized.cif",
        )

        s = Structure.from_file(structure_file)

        nn = MinimumDistanceNN()
        sg = StructureGraph.with_local_env_strategy(s, nn)

        molecules = sg.get_subgraphs_as_molecules()
        self.assertEqual(molecules[0].composition.formula, "H3 C1")
        self.assertEqual(len(molecules), 1)

        molecules = self.mos2_sg.get_subgraphs_as_molecules()
        self.assertEqual(len(molecules), 0)
Exemple #27
0
    def test_properties(self):

        self.assertEqual(self.mos2_sg.name, "bonds")
        self.assertEqual(self.mos2_sg.edge_weight_name, "bond_length")
        self.assertEqual(self.mos2_sg.edge_weight_unit, "Å")
        self.assertEqual(self.mos2_sg.get_coordination_of_site(0), 6)
        self.assertEqual(len(self.mos2_sg.get_connected_sites(0)), 6)
        self.assertTrue(
            isinstance(
                self.mos2_sg.get_connected_sites(0)[0].site, PeriodicSite))
        self.assertEqual(
            str(self.mos2_sg.get_connected_sites(0)[0].site.specie), "S")
        self.assertAlmostEqual(
            self.mos2_sg.get_connected_sites(
                0, jimage=(0, 0, 100))[0].site.frac_coords[2],
            100.303027,
        )

        # these two graphs should be equivalent
        for n in range(len(self.bc_square_sg)):
            self.assertEqual(
                self.bc_square_sg.get_coordination_of_site(n),
                self.bc_square_sg_r.get_coordination_of_site(n),
            )

        # test we're not getting duplicate connected sites
        # thanks to Jack D. Sundberg for reporting this bug

        # known example where this bug occurred due to edge weights not being
        # bit-for-bit identical in otherwise identical edges
        nacl_lattice = Lattice([
            [3.48543625, 0.0, 2.01231756],
            [1.16181208, 3.28610081, 2.01231756],
            [0.0, 0.0, 4.02463512],
        ])
        nacl = Structure(nacl_lattice, ["Na", "Cl"],
                         [[0, 0, 0], [0.5, 0.5, 0.5]])

        nacl_graph = StructureGraph.with_local_env_strategy(
            nacl, CutOffDictNN({("Cl", "Cl"): 5.0}))

        self.assertEqual(len(nacl_graph.get_connected_sites(1)), 12)
        self.assertEqual(len(nacl_graph.graph.get_edge_data(1, 1)), 6)
Exemple #28
0
    def process_item(self, item):
        """
        Calculates StructureGraphs (bonding information) for a material
        """

        topology_docs = []

        task_id = item['task_id']
        structure = Structure.from_dict(item['structure'])

        self.logger.debug("Calculating bonding for {}".format(task_id))

        # try all local_env strategies
        for strategy in self.strategies:
            method = strategy.__class__.__name__

            # failure statistics are interesting
            try:
                topology_docs.append({
                    'task_id':
                    task_id,
                    'method':
                    method,
                    'graph':
                    StructureGraph.with_local_env_strategy(
                        structure, strategy).as_dict(),
                    'successful':
                    True
                })
            except Exception as e:

                topology_docs.append({
                    'task_id': task_id,
                    'method': method,
                    'successful': False,
                    'error_message': str(e)
                })

                self.logger.warning(e)
                self.logger.warning("Failed to calculate bonding for {} using "
                                    "{} strategy.".format(task_id, method))

        return topology_docs
Exemple #29
0
def get_hash(structure: Structure, get_niggli=True):
    """
    This gets hash, using the structure graph as a part of the has

    Args:
        structure: pymatgen structure object
        get_niggli (bool):
    Returns:

    """
    if get_niggli:
        crystal = structure.get_reduced_structure()
    else:
        crystal = structure
    nn_strategy = JmolNN()
    sgraph_a = StructureGraph.with_local_env_strategy(crystal, nn_strategy)
    graph_hash = str(hash(sgraph_a.graph))
    comp_hash = str(hash(str(crystal.symbol_set)))
    density_hash = str(hash(crystal.density))
    return graph_hash + comp_hash + density_hash
Exemple #30
0
    def check_unbound(s: Structure,
                      whitelist: list = ['H'],
                      threshold: float = 2.5,
                      mode='naive') -> bool:
        """
        This uses the fact that unbound solvent is often in pores
        and more distant from all other atoms. So far this test focusses on water.

        Args:
            s (pymatgen structure object): structure to be checked
            whitelist (list): elements that are not considered in the check (they are basically removed from the
                structure)
            mode (str): checking mode. If 'naive' then a simple distance based check is used and a atom is detected
                as unbound it there is no other atom within the threshold distance.

        Returns:

        """

        crystal = s.copy()

        if whitelist:
            crystal.remove_species(whitelist)

        if mode == 'naive':
            for atom in crystal:
                neighbors = crystal.get_neighbors(atom, threshold)
                if len(neighbors) == 0:
                    return True
            return False

        if mode == 'graph':
            nn_strategy = JmolNN()
            sgraph = StructureGraph.with_local_env_strategy(
                crystal, nn_strategy)
            molecules = get_subgraphs_as_molecules_all(sgraph)

            if len(molecules) > 0:
                return True
            else:
                return False