Esempio n. 1
0
    def setUpClass(cls):
        if ob:
            EC_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "EC.xyz")), OpenBabelNN()
            )
            cls.EC_mg = metal_edge_extender(EC_mg)

            LiEC_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "LiEC.xyz")), OpenBabelNN()
            )
            cls.LiEC_mg = metal_edge_extender(LiEC_mg)

            LEDC_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "LEDC.xyz")), OpenBabelNN()
            )
            cls.LEDC_mg = metal_edge_extender(LEDC_mg)

            LEMC_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "LEMC.xyz")), OpenBabelNN()
            )
            cls.LEMC_mg = metal_edge_extender(LEMC_mg)

            cls.LiEC_reextended_entries = []
            entries = loadfn(os.path.join(test_dir, "LiEC_reextended_entries.json"))
            for entry in entries:
                if "optimized_molecule" in entry["output"]:
                    mol = entry["output"]["optimized_molecule"]
                else:
                    mol = entry["output"]["initial_molecule"]
                E = float(entry["output"]["final_energy"])
                H = float(entry["output"]["enthalpy"])
                S = float(entry["output"]["entropy"])
                mol_entry = MoleculeEntry(
                    molecule=mol,
                    energy=E,
                    enthalpy=H,
                    entropy=S,
                    entry_id=entry["task_id"],
                )
                if mol_entry.formula == "Li1":
                    if mol_entry.charge == 1:
                        cls.LiEC_reextended_entries.append(mol_entry)
                else:
                    cls.LiEC_reextended_entries.append(mol_entry)

            # dumpfn(cls.LiEC_reextended_entries, "unittest_input_molentries.json")

            with open(os.path.join(test_dir, "unittest_RN_build.pkl"), "rb") as input:
                cls.RN_build = pickle.load(input)

            with open(
                os.path.join(test_dir, "unittest_RN_pr_solved.pkl"), "rb"
            ) as input:
                cls.RN_pr_solved = pickle.load(input)
Esempio n. 2
0
    def setUpClass(cls) -> None:
        if ob:
            cls.LiEC_reextended_entries = []
            entries = loadfn(
                os.path.join(test_dir, "LiEC_reextended_entries.json"))
            for entry in entries:
                if "optimized_molecule" in entry["output"]:
                    mol = entry["output"]["optimized_molecule"]
                else:
                    mol = entry["output"]["initial_molecule"]
                E = float(entry["output"]["final_energy"])
                H = float(entry["output"]["enthalpy"])
                S = float(entry["output"]["entropy"])
                mol_entry = MoleculeEntry(
                    molecule=mol,
                    energy=E,
                    enthalpy=H,
                    entropy=S,
                    entry_id=entry["task_id"],
                )
                if mol_entry.formula == "Li1":
                    if mol_entry.charge == 1:
                        cls.LiEC_reextended_entries.append(mol_entry)
                else:
                    cls.LiEC_reextended_entries.append(mol_entry)

            LiEC_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "LiEC.xyz")),
                OpenBabelNN())
            cls.LiEC_mg = metal_edge_extender(LiEC_mg)

            LiEC_RO_mg = MoleculeGraph.with_local_env_strategy(
                Molecule.from_file(os.path.join(test_dir, "LiEC_RO.xyz")),
                OpenBabelNN())
            cls.LiEC_RO_mg = metal_edge_extender(LiEC_RO_mg)

            cls.LiEC_entry = None
            cls.LiEC_RO_entry = None

            for entry in cls.LiEC_reextended_entries:
                if (entry.formula == "C3 H4 Li1 O3" and entry.charge == 0
                        and entry.num_bonds == 12
                        and cls.LiEC_mg.isomorphic_to(entry.mol_graph)):
                    cls.LiEC_entry = entry
                elif (entry.formula == "C3 H4 Li1 O3" and entry.charge == 0
                      and entry.num_bonds == 11
                      and cls.LiEC_RO_mg.isomorphic_to(entry.mol_graph)):
                    cls.LiEC_RO_entry = entry
                if cls.LiEC_entry is not None and cls.LiEC_RO_entry is not None:
                    break
Esempio n. 3
0
    def __init__(self, db_entry, use_metal_edge_extender=True, optimized=True):

        # id
        identifier = str(db_entry["_id"])

        # pymatgen mol
        if optimized:
            if db_entry["state"] != "successful":
                raise UnsuccessfulEntryError
            try:
                pymatgen_mol = pymatgen.Molecule.from_dict(
                    db_entry["output"]["optimized_molecule"])
            except KeyError:
                pymatgen_mol = pymatgen.Molecule.from_dict(
                    db_entry["output"]["initial_molecule"])
                print("use initial_molecule for id: {}; job type:{} ".format(
                    db_entry["_id"], db_entry["output"]["job_type"]))
        else:
            pymatgen_mol = pymatgen.Molecule.from_dict(
                db_entry["input"]["initial_molecule"])

        # mol graph
        mol_graph = MoleculeGraph.with_local_env_strategy(
            pymatgen_mol, OpenBabelNN(order=True))
        if use_metal_edge_extender:
            mol_graph = metal_edge_extender(self.mol_graph)

        # free energy
        free_energy = self._get_free_energy(db_entry, self.id, self.formula)

        # init superclass
        super(MoleculeWrapperTaskCollection,
              self).__init__(mol_graph, free_energy, identifier)
Esempio n. 4
0
def find_mol_entry_from_xyz_and_charge(mol_entries, xyz_file_path, charge):
    """
    given a file 'molecule.xyz', find the mol_entry corresponding to the
    molecule graph with given charge
    """
    target_mol_graph = MoleculeGraph.with_local_env_strategy(
        Molecule.from_file(xyz_file_path), OpenBabelNN())

    # correction to the molecule graph
    target_mol_graph = metal_edge_extender(target_mol_graph)

    match = False
    index = -1
    while not match:
        index += 1
        mol_entry = mol_entries[index]
        species_mol_graph = mol_entry.mol_graph

        if mol_entry.charge == charge:
            match = target_mol_graph.isomorphic_to(species_mol_graph)

    if match:
        return mol_entry
    else:
        return None
Esempio n. 5
0
    def test_mol_to_mol_graph(self):
        mol = Molecule.from_file(
            (test_dir / "molecules" / "li2co3_1.xyz").as_posix())
        mg = MoleculeGraph.with_local_env_strategy(mol, OpenBabelNN())
        mg = metal_edge_extender(mg)

        self.assertEqual(mg, mol_to_mol_graph(mol))
Esempio n. 6
0
    def from_molecule_document(
        cls,
        mol_doc: Dict,
        correction: float = 0.0,
        parameters: Optional[Dict] = None,
        attribute=None,
    ):
        """
        Initialize a MoleculeEntry from a molecule document.

        Args:
            mol_doc: MongoDB molecule document (nested dictionary) that contains the
                molecule information.
            correction: A correction to be applied to the energy. This is used to modify
                the energy for certain analyses. Defaults to 0.0.
            parameters: An optional dict of parameters associated with
                the molecule. Defaults to None.
            attribute: Optional attribute of the entry. This can be used to
                specify that the entry is a newly found compound, or to specify
                a particular label for the entry, or else ... Used for further
                analysis and plotting purposes. An attribute can be anything
                but must be MSONable.
        """
        try:
            if isinstance(mol_doc["molecule"], Molecule):
                molecule = mol_doc["molecule"]
            else:
                molecule = Molecule.from_dict(mol_doc["molecule"])
            energy = mol_doc["energy_Ha"]
            enthalpy = mol_doc["enthalpy_kcal/mol"]
            entropy = mol_doc["entropy_cal/molK"]
            entry_id = mol_doc["task_id"]
        except KeyError as e:
            raise MoleculeEntryError(
                "Unable to construct molecule entry from molecule document; missing "
                f"attribute {e} in `mol_doc`.")

        if "mol_graph" in mol_doc:
            if isinstance(mol_doc["mol_graph"], MoleculeGraph):
                mol_graph = mol_doc["mol_graph"]
            else:
                mol_graph = MoleculeGraph.from_dict(mol_doc["mol_graph"])
        else:
            mol_graph = MoleculeGraph.with_local_env_strategy(
                molecule, OpenBabelNN())
            mol_graph = metal_edge_extender(mol_graph)

        return cls(
            molecule=molecule,
            energy=energy,
            correction=correction,
            enthalpy=enthalpy,
            entropy=entropy,
            parameters=parameters,
            entry_id=entry_id,
            attribute=attribute,
            mol_graph=mol_graph,
        )
Esempio n. 7
0
    def __init__(
        self,
        molecule: Molecule,
        energy: float,
        correction: float = 0.0,
        enthalpy: Optional[float] = None,
        entropy: Optional[float] = None,
        parameters: Optional[Dict] = None,
        entry_id: Optional[Any] = None,
        attribute=None,
        mol_doc: Optional[Dict] = None,
        mol_graph: Optional[MoleculeGraph] = None,
    ):

        self.uncorrected_energy = energy
        self.correction = correction
        self.enthalpy = enthalpy
        self.entropy = entropy
        self.parameters = parameters if parameters else {}
        self.entry_id = entry_id
        self.attribute = attribute
        self.mol_doc = mol_doc if mol_doc else {}
        self.mol_graph = mol_graph

        if self.mol_doc != {}:

            self.enthalpy = self.mol_doc["enthalpy_kcal/mol"]
            self.entropy = self.mol_doc["entropy_cal/molK"]
            self.entry_id = self.mol_doc["task_id"]
            if "mol_graph" in self.mol_doc:
                if isinstance(self.mol_doc["mol_graph"], MoleculeGraph):
                    self.mol_graph = self.mol_doc["mol_graph"]
                else:
                    self.mol_graph = MoleculeGraph.from_dict(
                        self.mol_doc["mol_graph"])
            else:
                mol_graph = MoleculeGraph.with_local_env_strategy(
                    molecule, OpenBabelNN())
                self.mol_graph = metal_edge_extender(mol_graph)
        else:
            if self.mol_graph is None:
                mol_graph = MoleculeGraph.with_local_env_strategy(
                    molecule, OpenBabelNN())
                self.mol_graph = metal_edge_extender(mol_graph)
Esempio n. 8
0
def mol_to_mol_graph(molecule: Union[Molecule, MoleculeGraph]):
    """
    Convert a Molecule to a MoleculeGraph using a default connectivity
    algorithm.

    Args:
        molecule (Molecule): Molecule to be converted

    Returns:
        mol_graph: MoleculeGraph
    """

    if isinstance(molecule, MoleculeGraph):
        return molecule
    else:
        mol_graph = MoleculeGraph.with_local_env_strategy(molecule, OpenBabelNN())
        return metal_edge_extender(mol_graph)
Esempio n. 9
0
 def test_metal_edge_extender(self):
     mol_graph = MoleculeGraph.with_edges(molecule=self.LiEC,
                                          edges={
                                              (0, 2): None,
                                              (0, 1): None,
                                              (1, 3): None,
                                              (1, 4): None,
                                              (2, 7): None,
                                              (2, 5): None,
                                              (2, 8): None,
                                              (3, 6): None,
                                              (4, 5): None,
                                              (5, 9): None,
                                              (5, 10): None
                                          })
     self.assertEqual(len(mol_graph.graph.edges), 11)
     extended_mol_graph = metal_edge_extender(mol_graph)
     self.assertEqual(len(mol_graph.graph.edges), 12)
Esempio n. 10
0
    def test_union_molgraph(self):

        with self.assertRaises(ValueError):
            _ = union_molgraph([])

        # Test "good", well-behaved case
        good_one = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "molecules" / "union" / "good" /
                                "1.xyz").as_posix()), OpenBabelNN())
        good_one = metal_edge_extender(good_one)
        good_two = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "molecules" / "union" / "good" /
                                "2.xyz").as_posix()), OpenBabelNN())
        good_two = metal_edge_extender(good_two)
        good_union = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "molecules" / "union" / "good" /
                                "union.xyz").as_posix()), OpenBabelNN())
        good_union = metal_edge_extender(good_union)

        good = union_molgraph([good_one, good_two])
        self.assertTrue(good_union.isomorphic_to(good))

        # Test "bad" case where proximity might be an issue
        bad_one = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "molecules" / "union" / "bad" /
                                "1.xyz").as_posix()), OpenBabelNN())
        bad_one = metal_edge_extender(bad_one)
        bad_two = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "molecules" / "union" / "bad" /
                                "2.xyz").as_posix()), OpenBabelNN())
        bad_two = metal_edge_extender(bad_two)
        bad_union = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file(
                (test_dir / "molecules" / "union" / "bad" / "union.xyz")),
            OpenBabelNN())
        bad_union = metal_edge_extender(bad_union)

        bad = union_molgraph([bad_one, bad_two])
        self.assertTrue(bad_union.isomorphic_to(bad))

        with self.assertRaises(ValueError):
            _ = union_molgraph([bad_one, bad_two], validate_proximity=True)
Esempio n. 11
0
    def test_get_reaction_graphs(self):

        # Test that isomorphic graphs return themselves
        li2co3 = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file(
                (test_dir / "molecules" / "li2co3_1.xyz").as_posix()),
            OpenBabelNN())
        li2co3 = metal_edge_extender(li2co3)
        li2co3_copy = copy.deepcopy(li2co3)

        self.assertEqual(get_reaction_graphs(li2co3, li2co3_copy), [li2co3])

        # Test for case where graphs cannot be compared (different species, etc.)
        ethane = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file(
                (test_dir / "molecules" / "ethane.mol").as_posix()),
            OpenBabelNN())

        self.assertEqual(get_reaction_graphs(li2co3, ethane), list())

        # Test for case of a single bond-breaking
        break_rct = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "break" / "rct.xyz").as_posix()),
            OpenBabelNN())
        break_rct = metal_edge_extender(break_rct)
        break_pro = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "break" / "pro.xyz").as_posix()),
            OpenBabelNN())
        break_pro = metal_edge_extender(break_pro)

        break_rxn = get_reaction_graphs(break_rct, break_pro)
        self.assertEqual(len(break_rxn), 1)
        self.assertTrue(break_rxn[0].isomorphic_to(break_rct))
        # for edge in break_rxn[0].graph.edges(data=True):
        #     print(edge)
        self.assertTrue(break_rxn[0].graph[4][5][0].get("broken", False))
        self.assertFalse(break_rxn[0].graph[4][5][0].get("formed", True))

        # Test for case of a single bond-forming
        form_rct = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "form" / "rct.xyz").as_posix()), OpenBabelNN())
        form_rct = metal_edge_extender(form_rct)
        form_pro = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "form" / "pro.xyz").as_posix()), OpenBabelNN())
        form_pro = metal_edge_extender(form_pro)

        form_rxn = get_reaction_graphs(form_rct, form_pro)
        self.assertEqual(len(form_rxn), 1)
        self.assertTrue(form_rxn[0].isomorphic_to(form_pro))
        self.assertTrue(form_rxn[0].graph[0][3][0].get("formed", False))
        self.assertFalse(form_rxn[0].graph[0][3][0].get("broken", True))

        # Test for case of complex bond breaking and formation
        bf_rct = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "break_form" / "rct.xyz").as_posix()),
            OpenBabelNN())
        bf_rct = metal_edge_extender(bf_rct)
        bf_pro = MoleculeGraph.with_local_env_strategy(
            Molecule.from_file((test_dir / "reactions" / "isomorphism" /
                                "break_form" / "pro.xyz").as_posix()),
            OpenBabelNN())
        bf_pro = metal_edge_extender(bf_pro)

        bf_rxn = get_reaction_graphs(bf_rct, bf_pro)
        self.assertEqual(len(bf_rxn), 0)

        bf_rxn = get_reaction_graphs(bf_rct,
                                     bf_pro,
                                     allowed_break=2,
                                     allowed_form=1,
                                     stop_at_one=True)
        self.assertEqual(len(bf_rxn), 1)

        bf_rxn = get_reaction_graphs(bf_rct,
                                     bf_pro,
                                     allowed_break=2,
                                     allowed_form=1,
                                     stop_at_one=False)
        self.assertEqual(len(bf_rxn), 2)

        self.assertTrue(bf_rxn[0].graph[0][8][0].get("broken", False))
        self.assertTrue(bf_rxn[0].graph[6][12][0].get("broken", False))
        self.assertTrue(bf_rxn[0].graph[8][12][0].get("formed", False))

        self.assertTrue(bf_rxn[1].graph[0][9][0].get("broken", False))
        self.assertTrue(bf_rxn[1].graph[6][12][0].get("broken", False))
        self.assertTrue(bf_rxn[1].graph[9][12][0].get("formed", False))
Esempio n. 12
0
 def convert_to_babel_mol_graph(self, use_metal_edge_extender=True):
     self.mol_graph = MoleculeGraph.with_local_env_strategy(
         self.pymatgen_mol, OpenBabelNN(order=True))
     if use_metal_edge_extender:
         self.mol_graph = metal_edge_extender(self.mol_graph)
Esempio n. 13
0
    "..",
    "test_files",
    "reaction_network_files",
)

try:
    import openbabel as ob
except ImportError:
    ob = None
""" 
Create a reaction network for testing from LiEC entries
"""
if ob:
    EC_mg = MoleculeGraph.with_local_env_strategy(
        Molecule.from_file(os.path.join(test_dir, "EC.xyz")), OpenBabelNN())
    EC_mg = metal_edge_extender(EC_mg)

    LiEC_mg = MoleculeGraph.with_local_env_strategy(
        Molecule.from_file(os.path.join(test_dir, "LiEC.xyz")), OpenBabelNN())
    LiEC_mg = metal_edge_extender(LiEC_mg)
    LEDC_mg = MoleculeGraph.with_local_env_strategy(
        Molecule.from_file(os.path.join(test_dir, "LEDC.xyz")), OpenBabelNN())
    LEDC_mg = metal_edge_extender(LEDC_mg)
    LEMC_mg = MoleculeGraph.with_local_env_strategy(
        Molecule.from_file(os.path.join(test_dir, "LEMC.xyz")), OpenBabelNN())
    LEMC_mg = metal_edge_extender(LEMC_mg)
LiEC_reextended_entries = []
entries = loadfn(os.path.join(test_dir, "LiEC_reextended_entries.json"))
for entry in entries:
    if "optimized_molecule" in entry["output"]:
        mol = entry["output"]["optimized_molecule"]