コード例 #1
0
def molecule_to_schrodinger_struct(molecule: Molecule):
    """
    Convert a pymatgen Molecule object to a Schrodinger Structure object

    Args:
        molecule (pymatgen.core.structure.Molecule): Molecule to be converted

    Returns:
        struct: schrodinger.structure.Structure object
    """

    # First need to convert molecule to file to use StructureReader

    file_suffix = random.randint(1, 100000000)
    molecule.to('sdf', "temp_conversion{}.sdf".format(file_suffix))

    reader = StructureReader("temp_conversion{}.sdf".format(file_suffix))

    # Assume only one structure (should be the case for a single SDF file)
    struct = [r for r in reader][0]

    for atom in struct.atom:
        atom.formal_charge = 0
    struct.atom[1].formal_charge = molecule.charge

    Path("temp_conversion{}.sdf".format(file_suffix))

    return struct
コード例 #2
0
ファイル: ion_arranger.py プロジェクト: xhqu1981/rubicon
 def write_structure(self, candidate, filename="result.xyz"):
     fragments_coords = self.decode_solution(candidate)
     mol_elements = self.get_mol_species(self.molecule)
     fragments_elements = []
     for frag, num_frag in zip(self.fragments, self.nums_fragments):
         fragments_elements.extend([self.get_mol_species(frag)] * num_frag)
     species = []
     coords_au = []
     species.extend(mol_elements)
     coords_au.extend(self.mol_coords)
     for elements, c in zip(fragments_elements, fragments_coords):
         species.extend(elements)
         coords_au.extend(c)
     coords_ang = [[x / AtomicRadiusUtils.angstrom2au for x in c] for c in
                   coords_au]
     pmg_mol = Molecule(species, coords_ang)
     file_format = os.path.splitext(filename)[1][1:]
     pmg_mol.to(file_format, filename)
コード例 #3
0
class MoleculeTest(PymatgenTest):

    def setUp(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        self.mol = Molecule(["C", "H", "H", "H", "H"], coords)

    def test_mutable_sequence_methods(self):
        s = self.mol
        s[1] = ("F", [0.5, 0.5, 0.5])
        self.assertEqual(s.formula, "H3 C1 F1")
        self.assertArrayAlmostEqual(s[1].coords, [0.5, 0.5, 0.5])
        s.reverse()
        self.assertEqual(s[0].specie, Element("H"))
        self.assertArrayAlmostEqual(s[0].coords,
                                    [-0.513360, 0.889165, -0.363000])
        del s[1]
        self.assertEqual(s.formula, "H2 C1 F1")
        s[3] = "N", [0,0,0], {"charge": 4}
        self.assertEqual(s.formula, "H2 N1 F1")
        self.assertEqual(s[3].charge, 4)

    def test_insert_remove_append(self):
        mol = self.mol
        mol.insert(1, "O", [0.5, 0.5, 0.5])
        self.assertEqual(mol.formula, "H4 C1 O1")
        del mol[2]
        self.assertEqual(mol.formula, "H3 C1 O1")
        mol.set_charge_and_spin(0)
        self.assertEqual(mol.spin_multiplicity, 2)
        mol.append("N", [1, 1, 1])
        self.assertEqual(mol.formula, "H3 C1 N1 O1")
        self.assertRaises(TypeError, dict, [(mol, 1)])
        mol.remove_sites([0, 1])
        self.assertEqual(mol.formula, "H3 N1")

    def test_translate_sites(self):
        self.mol.translate_sites([0, 1], [0.5, 0.5, 0.5])
        self.assertArrayEqual(self.mol.cart_coords[0],
                              [0.5, 0.5, 0.5])

    def test_replace(self):
        self.mol[0] = "Ge"
        self.assertEqual(self.mol.formula, "Ge1 H4")

        self.mol.replace_species({Element("Ge"): {Element("Ge"): 0.5,
                                                  Element("Si"): 0.5}})
        self.assertEqual(self.mol.formula, "Si0.5 Ge0.5 H4")

        #this should change the .5Si .5Ge sites to .75Si .25Ge
        self.mol.replace_species({Element("Ge"): {Element("Ge"): 0.5,
                                                  Element("Si"): 0.5}})
        self.assertEqual(self.mol.formula, "Si0.75 Ge0.25 H4")

        d = 0.1
        pre_perturbation_sites = self.mol.sites[:]
        self.mol.perturb(distance=d)
        post_perturbation_sites = self.mol.sites

        for i, x in enumerate(pre_perturbation_sites):
            self.assertAlmostEqual(x.distance(post_perturbation_sites[i]), d,
                                   3, "Bad perturbation distance")

    def test_add_site_property(self):
        self.mol.add_site_property("charge", [4.1, -2, -2, -2, -2])
        self.assertEqual(self.mol[0].charge, 4.1)
        self.assertEqual(self.mol[1].charge, -2)

        self.mol.add_site_property("magmom", [3, 2, 2, 2, 2])
        self.assertEqual(self.mol[0].charge, 4.1)
        self.assertEqual(self.mol[0].magmom, 3)

    def test_to_from_dict(self):
        d = self.mol.as_dict()
        mol2 = Molecule.from_dict(d)
        self.assertEqual(type(mol2), Molecule)

    def test_apply_operation(self):
        op = SymmOp.from_axis_angle_and_translation([0, 0, 1], 90)
        self.mol.apply_operation(op)
        self.assertArrayAlmostEqual(self.mol[2].coords,
                                    [0.000000, 1.026719, -0.363000])

    def test_substitute(self):
        coords = [[0.000000, 0.000000, 1.08],
                  [0.000000, 0.000000, 0.000000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        sub = Molecule(["X", "C", "H", "H", "H"], coords)
        self.mol.substitute(1, sub)
        self.assertAlmostEqual(self.mol.get_distance(0, 4), 1.54)
        f = Molecule(["X", "F"], [[0, 0, 0], [0, 0, 1.11]])
        self.mol.substitute(2, f)
        self.assertAlmostEqual(self.mol.get_distance(0, 7), 1.35)
        oh = Molecule(["X", "O", "H"],
                      [[0, 0.780362, -.456316], [0, 0, .114079],
                       [0, -.780362, -.456316]])
        self.mol.substitute(1, oh)
        self.assertAlmostEqual(self.mol.get_distance(0, 7), 1.43)
        self.mol.substitute(3, "methyl")
        self.assertEqual(self.mol.formula, "H7 C3 O1 F1")
        coords = [[0.00000, 1.40272, 0.00000],
                  [0.00000, 2.49029, 0.00000],
                  [-1.21479, 0.70136, 0.00000],
                  [-2.15666, 1.24515, 0.00000],
                  [-1.21479, -0.70136, 0.00000],
                  [-2.15666, -1.24515, 0.00000],
                  [0.00000, -1.40272, 0.00000],
                  [0.00000, -2.49029, 0.00000],
                  [1.21479, -0.70136, 0.00000],
                  [2.15666, -1.24515, 0.00000],
                  [1.21479, 0.70136, 0.00000],
                  [2.15666, 1.24515, 0.00000]]
        benzene = Molecule(["C", "H", "C", "H", "C", "H", "C", "H", "C", "H",
                            "C", "H"], coords)
        benzene.substitute(1, sub)
        self.assertEqual(benzene.formula, "H8 C7")
        #Carbon attached should be in plane.
        self.assertAlmostEqual(benzene[11].coords[2], 0)

    def test_to_from_file_string(self):
        for fmt in ["xyz", "json", "g03"]:
            s = self.mol.to(fmt=fmt)
            self.assertIsNotNone(s)
            m = Molecule.from_str(s, fmt=fmt)
            self.assertEqual(m, self.mol)
            self.assertIsInstance(m, Molecule)

        self.mol.to(filename="CH4_testing.xyz")
        self.assertTrue(os.path.exists("CH4_testing.xyz"))
        os.remove("CH4_testing.xyz")
コード例 #4
0
class IMoleculeTest(PymatgenTest):

    def setUp(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        self.coords = coords
        self.mol = Molecule(["C", "H", "H", "H", "H"], coords)

    def test_bad_molecule(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.36301]]
        self.assertRaises(StructureError, Molecule,
                          ["C", "H", "H", "H", "H", "H"], coords,
                          validate_proximity=True)

    def test_get_angle_dihedral(self):
        self.assertAlmostEqual(self.mol.get_angle(1, 0, 2), 109.47122144618737)
        self.assertAlmostEqual(self.mol.get_angle(3, 1, 2), 60.00001388659683)
        self.assertAlmostEqual(self.mol.get_dihedral(0, 1, 2, 3),
                               - 35.26438851071765)

        coords = list()
        coords.append([0, 0, 0])
        coords.append([0, 0, 1])
        coords.append([0, 1, 1])
        coords.append([1, 1, 1])
        self.mol2 = Molecule(["C", "O", "N", "S"], coords)
        self.assertAlmostEqual(self.mol2.get_dihedral(0, 1, 2, 3), -90)

    def test_get_covalent_bonds(self):
        self.assertEqual(len(self.mol.get_covalent_bonds()), 4)

    def test_properties(self):
        self.assertEqual(len(self.mol), 5)
        self.assertTrue(self.mol.is_ordered)
        self.assertEqual(self.mol.formula, "H4 C1")

    def test_repr_str(self):
        ans = """Full Formula (H4 C1)
Reduced Formula: H4C
Charge = 0, Spin Mult = 1
Sites (5)
0 C     0.000000     0.000000     0.000000
1 H     0.000000     0.000000     1.089000
2 H     1.026719     0.000000    -0.363000
3 H    -0.513360    -0.889165    -0.363000
4 H    -0.513360     0.889165    -0.363000"""
        self.assertEqual(self.mol.__str__(), ans)
        ans = """Molecule Summary
Site: C (0.0000, 0.0000, 0.0000)
Site: H (0.0000, 0.0000, 1.0890)
Site: H (1.0267, 0.0000, -0.3630)
Site: H (-0.5134, -0.8892, -0.3630)
Site: H (-0.5134, 0.8892, -0.3630)"""
        self.assertEqual(repr(self.mol), ans)

    def test_site_properties(self):
        propertied_mol = Molecule(["C", "H", "H", "H", "H"], self.coords,
                                  site_properties={'magmom':
                                                   [0.5, -0.5, 1, 2, 3]})
        self.assertEqual(propertied_mol[0].magmom, 0.5)
        self.assertEqual(propertied_mol[1].magmom, -0.5)

    def test_get_boxed_structure(self):
        s = self.mol.get_boxed_structure(9, 9, 9)
        # C atom should be in center of box.
        self.assertArrayAlmostEqual(s[4].frac_coords,
                                    [0.50000001,  0.5,  0.5])
        self.assertArrayAlmostEqual(s[1].frac_coords,
                                    [0.6140799, 0.5,  0.45966667])
        self.assertRaises(ValueError, self.mol.get_boxed_structure, 1, 1, 1)
        s2 = self.mol.get_boxed_structure(5, 5, 5, (2, 3, 4))
        self.assertEqual(len(s2), 24 * 5)
        self.assertEqual(s2.lattice.abc, (10, 15, 20))

    def test_get_distance(self):
        self.assertAlmostEqual(self.mol.get_distance(0, 1), 1.089)

    def test_get_neighbors(self):
        nn = self.mol.get_neighbors(self.mol[0], 1)
        self.assertEqual(len(nn), 0)
        nn = self.mol.get_neighbors(self.mol[0], 2)
        self.assertEqual(len(nn), 4)

    def test_get_neighbors_in_shell(self):
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 0, 1)
        self.assertEqual(len(nn), 1)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 1, 0.9)
        self.assertEqual(len(nn), 4)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 1, 0.9)
        self.assertEqual(len(nn), 4)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 2, 0.1)
        self.assertEqual(len(nn), 0)

    def test_get_dist_matrix(self):
        ans = [[0.0, 1.089, 1.08899995636, 1.08900040717, 1.08900040717],
               [1.089, 0.0, 1.77832952654, 1.7783298026, 1.7783298026],
               [1.08899995636, 1.77832952654, 0.0, 1.77833003783,
                1.77833003783],
               [1.08900040717, 1.7783298026, 1.77833003783, 0.0, 1.77833],
               [1.08900040717, 1.7783298026, 1.77833003783, 1.77833, 0.0]]
        self.assertArrayAlmostEqual(self.mol.distance_matrix, ans)

    def test_break_bond(self):
        (mol1, mol2) = self.mol.break_bond(0, 1)
        self.assertEqual(mol1.formula, "H3 C1")
        self.assertEqual(mol2.formula, "H1")

    def test_prop(self):
        self.assertEqual(self.mol.charge, 0)
        self.assertEqual(self.mol.spin_multiplicity, 1)
        self.assertEqual(self.mol.nelectrons, 10)
        self.assertArrayAlmostEqual(self.mol.center_of_mass, [0, 0, 0])
        self.assertRaises(ValueError, Molecule, ["C", "H", "H", "H", "H"],
                          self.coords, charge=1, spin_multiplicity=1)
        mol = Molecule(["C", "H", "H", "H", "H"], self.coords, charge=1)
        self.assertEqual(mol.spin_multiplicity, 2)
        self.assertEqual(mol.nelectrons, 9)

        #Triplet O2
        mol = IMolecule(["O"] * 2, [[0, 0, 0], [0, 0, 1.2]],
                        spin_multiplicity=3)
        self.assertEqual(mol.spin_multiplicity, 3)

    def test_equal(self):
        mol = IMolecule(["C", "H", "H", "H", "H"], self.coords, charge=1)
        self.assertNotEqual(mol, self.mol)

    def test_get_centered_molecule(self):
        mol = IMolecule(["O"] * 2, [[0, 0, 0], [0, 0, 1.2]],
                        spin_multiplicity=3)
        centered = mol.get_centered_molecule()
        self.assertArrayAlmostEqual(centered.center_of_mass, [0, 0, 0])

    def test_to_from_dict(self):
        d = self.mol.as_dict()
        mol2 = IMolecule.from_dict(d)
        self.assertEqual(type(mol2), IMolecule)
        propertied_mol = Molecule(["C", "H", "H", "H", "H"], self.coords,
                                  charge=1,
                                  site_properties={'magmom':
                                                   [0.5, -0.5, 1, 2, 3]})
        d = propertied_mol.as_dict()
        self.assertEqual(d['sites'][0]['properties']['magmom'], 0.5)
        mol = Molecule.from_dict(d)
        self.assertEqual(propertied_mol, mol)
        self.assertEqual(mol[0].magmom, 0.5)
        self.assertEqual(mol.formula, "H4 C1")
        self.assertEqual(mol.charge, 1)

    def test_to_from_file_string(self):
        for fmt in ["xyz", "json", "g03", "yaml"]:
            s = self.mol.to(fmt=fmt)
            self.assertIsNotNone(s)
            m = IMolecule.from_str(s, fmt=fmt)
            self.assertEqual(m, self.mol)
            self.assertIsInstance(m, IMolecule)

        self.mol.to(filename="CH4_testing.xyz")
        self.assertTrue(os.path.exists("CH4_testing.xyz"))
        os.remove("CH4_testing.xyz")
        self.mol.to(filename="CH4_testing.yaml")
        self.assertTrue(os.path.exists("CH4_testing.yaml"))
        mol = Molecule.from_file("CH4_testing.yaml")
        self.assertEqual(self.mol, mol)
        os.remove("CH4_testing.yaml")
コード例 #5
0
if len(argv) < 3:
    exit("Usage: convert_trajectory_xyzs.py initial_molecule_file, trajectory, to_dir")

initial_molecule_file = argv[1]
trajectory = argv[2]
to_dir = argv[3]

init_mol = Molecule.from_file(initial_molecule_file)
species = [str(e) for e in init_mol.species]
num_atoms = len(species)

if to_dir not in os.listdir():
    os.mkdir(to_dir)

iteration = 0
num_agent = 0
with open(trajectory) as traj_file:
    lines = traj_file.readlines()
    num_agents = int(lines[1].split()[1])

    for line in lines[2:]:
        if line == "\n":
            iteration += 1
            num_agent = 0
        elif "." not in line:
            continue
        else:
            coords = np.array([float(e) for e in line.strip().split(" ")]).reshape(num_atoms, 3)
            mol = Molecule(species, coords)
            mol.to("xyz", os.path.join(to_dir, "{}_{}.xyz".format(iteration,num_agent)))
            num_agent += 1
コード例 #6
0
ファイル: test_structure.py プロジェクト: xhqu1981/pymatgen
class IMoleculeTest(PymatgenTest):
    def setUp(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        self.coords = coords
        self.mol = Molecule(["C", "H", "H", "H", "H"], coords)

    def test_set_item(self):
        s = self.mol.copy()
        s[0] = "Si"
        self.assertEqual(s.formula, "Si1 H4")
        s[(0, 1)] = "Ge"
        self.assertEqual(s.formula, "Ge2 H3")
        s[0:2] = "Sn"
        self.assertEqual(s.formula, "Sn2 H3")

        s = self.mol.copy()
        s["H"] = "F"
        self.assertEqual(s.formula, "C1 F4")
        s["C"] = "C0.25Si0.5"
        self.assertEqual(s.formula, "Si0.5 C0.25 F4")
        s["C"] = "C0.25Si0.5"
        self.assertEqual(s.formula, "Si0.625 C0.0625 F4")

    def test_bad_molecule(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.36301]]
        self.assertRaises(StructureError,
                          Molecule, ["C", "H", "H", "H", "H", "H"],
                          coords,
                          validate_proximity=True)

    def test_get_angle_dihedral(self):
        self.assertAlmostEqual(self.mol.get_angle(1, 0, 2), 109.47122144618737)
        self.assertAlmostEqual(self.mol.get_angle(3, 1, 2), 60.00001388659683)
        self.assertAlmostEqual(self.mol.get_dihedral(0, 1, 2, 3),
                               -35.26438851071765)

        coords = list()
        coords.append([0, 0, 0])
        coords.append([0, 0, 1])
        coords.append([0, 1, 1])
        coords.append([1, 1, 1])
        self.mol2 = Molecule(["C", "O", "N", "S"], coords)
        self.assertAlmostEqual(self.mol2.get_dihedral(0, 1, 2, 3), -90)

    def test_get_covalent_bonds(self):
        self.assertEqual(len(self.mol.get_covalent_bonds()), 4)

    def test_properties(self):
        self.assertEqual(len(self.mol), 5)
        self.assertTrue(self.mol.is_ordered)
        self.assertEqual(self.mol.formula, "H4 C1")

    def test_repr_str(self):
        ans = """Full Formula (H4 C1)
Reduced Formula: H4C
Charge = 0, Spin Mult = 1
Sites (5)
0 C     0.000000     0.000000     0.000000
1 H     0.000000     0.000000     1.089000
2 H     1.026719     0.000000    -0.363000
3 H    -0.513360    -0.889165    -0.363000
4 H    -0.513360     0.889165    -0.363000"""
        self.assertEqual(self.mol.__str__(), ans)
        ans = """Molecule Summary
Site: C (0.0000, 0.0000, 0.0000)
Site: H (0.0000, 0.0000, 1.0890)
Site: H (1.0267, 0.0000, -0.3630)
Site: H (-0.5134, -0.8892, -0.3630)
Site: H (-0.5134, 0.8892, -0.3630)"""
        self.assertEqual(repr(self.mol), ans)

    def test_site_properties(self):
        propertied_mol = Molecule(
            ["C", "H", "H", "H", "H"],
            self.coords,
            site_properties={'magmom': [0.5, -0.5, 1, 2, 3]})
        self.assertEqual(propertied_mol[0].magmom, 0.5)
        self.assertEqual(propertied_mol[1].magmom, -0.5)

    def test_get_boxed_structure(self):
        s = self.mol.get_boxed_structure(9, 9, 9)
        # C atom should be in center of box.
        self.assertArrayAlmostEqual(s[4].frac_coords, [0.50000001, 0.5, 0.5])
        self.assertArrayAlmostEqual(s[1].frac_coords,
                                    [0.6140799, 0.5, 0.45966667])
        self.assertRaises(ValueError, self.mol.get_boxed_structure, 1, 1, 1)
        s2 = self.mol.get_boxed_structure(5, 5, 5, (2, 3, 4))
        self.assertEqual(len(s2), 24 * 5)
        self.assertEqual(s2.lattice.abc, (10, 15, 20))

        # Test offset option
        s3 = self.mol.get_boxed_structure(9, 9, 9, offset=[0.5, 0.5, 0.5])
        self.assertArrayAlmostEqual(s3[4].coords, [5, 5, 5])
        # Test no_cross option
        self.assertRaises(ValueError,
                          self.mol.get_boxed_structure,
                          5,
                          5,
                          5,
                          offset=[10, 10, 10],
                          no_cross=True)

    def test_get_distance(self):
        self.assertAlmostEqual(self.mol.get_distance(0, 1), 1.089)

    def test_get_neighbors(self):
        nn = self.mol.get_neighbors(self.mol[0], 1)
        self.assertEqual(len(nn), 0)
        nn = self.mol.get_neighbors(self.mol[0], 2)
        self.assertEqual(len(nn), 4)

    def test_get_neighbors_in_shell(self):
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 0, 1)
        self.assertEqual(len(nn), 1)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 1, 0.9)
        self.assertEqual(len(nn), 4)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 1, 0.9)
        self.assertEqual(len(nn), 4)
        nn = self.mol.get_neighbors_in_shell([0, 0, 0], 2, 0.1)
        self.assertEqual(len(nn), 0)

    def test_get_dist_matrix(self):
        ans = [[0.0, 1.089, 1.08899995636, 1.08900040717, 1.08900040717],
               [1.089, 0.0, 1.77832952654, 1.7783298026, 1.7783298026],
               [
                   1.08899995636, 1.77832952654, 0.0, 1.77833003783,
                   1.77833003783
               ], [1.08900040717, 1.7783298026, 1.77833003783, 0.0, 1.77833],
               [1.08900040717, 1.7783298026, 1.77833003783, 1.77833, 0.0]]
        self.assertArrayAlmostEqual(self.mol.distance_matrix, ans)

    def test_break_bond(self):
        (mol1, mol2) = self.mol.break_bond(0, 1)
        self.assertEqual(mol1.formula, "H3 C1")
        self.assertEqual(mol2.formula, "H1")

    def test_prop(self):
        self.assertEqual(self.mol.charge, 0)
        self.assertEqual(self.mol.spin_multiplicity, 1)
        self.assertEqual(self.mol.nelectrons, 10)
        self.assertArrayAlmostEqual(self.mol.center_of_mass, [0, 0, 0])
        self.assertRaises(ValueError,
                          Molecule, ["C", "H", "H", "H", "H"],
                          self.coords,
                          charge=1,
                          spin_multiplicity=1)
        mol = Molecule(["C", "H", "H", "H", "H"], self.coords, charge=1)
        self.assertEqual(mol.spin_multiplicity, 2)
        self.assertEqual(mol.nelectrons, 9)

        #Triplet O2
        mol = IMolecule(["O"] * 2, [[0, 0, 0], [0, 0, 1.2]],
                        spin_multiplicity=3)
        self.assertEqual(mol.spin_multiplicity, 3)

    def test_equal(self):
        mol = IMolecule(["C", "H", "H", "H", "H"], self.coords, charge=1)
        self.assertNotEqual(mol, self.mol)

    def test_get_centered_molecule(self):
        mol = IMolecule(["O"] * 2, [[0, 0, 0], [0, 0, 1.2]],
                        spin_multiplicity=3)
        centered = mol.get_centered_molecule()
        self.assertArrayAlmostEqual(centered.center_of_mass, [0, 0, 0])

    def test_to_from_dict(self):
        d = self.mol.as_dict()
        mol2 = IMolecule.from_dict(d)
        self.assertEqual(type(mol2), IMolecule)
        propertied_mol = Molecule(
            ["C", "H", "H", "H", "H"],
            self.coords,
            charge=1,
            site_properties={'magmom': [0.5, -0.5, 1, 2, 3]})
        d = propertied_mol.as_dict()
        self.assertEqual(d['sites'][0]['properties']['magmom'], 0.5)
        mol = Molecule.from_dict(d)
        self.assertEqual(propertied_mol, mol)
        self.assertEqual(mol[0].magmom, 0.5)
        self.assertEqual(mol.formula, "H4 C1")
        self.assertEqual(mol.charge, 1)

    def test_to_from_file_string(self):
        for fmt in ["xyz", "json", "g03", "yaml"]:
            s = self.mol.to(fmt=fmt)
            self.assertIsNotNone(s)
            m = IMolecule.from_str(s, fmt=fmt)
            self.assertEqual(m, self.mol)
            self.assertIsInstance(m, IMolecule)

        self.mol.to(filename="CH4_testing.xyz")
        self.assertTrue(os.path.exists("CH4_testing.xyz"))
        os.remove("CH4_testing.xyz")
        self.mol.to(filename="CH4_testing.yaml")
        self.assertTrue(os.path.exists("CH4_testing.yaml"))
        mol = Molecule.from_file("CH4_testing.yaml")
        self.assertEqual(self.mol, mol)
        os.remove("CH4_testing.yaml")
コード例 #7
0
ファイル: test_structure.py プロジェクト: xhqu1981/pymatgen
class MoleculeTest(PymatgenTest):
    def setUp(self):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        self.mol = Molecule(["C", "H", "H", "H", "H"], coords)

    def test_mutable_sequence_methods(self):
        s = self.mol
        s[1] = ("F", [0.5, 0.5, 0.5])
        self.assertEqual(s.formula, "H3 C1 F1")
        self.assertArrayAlmostEqual(s[1].coords, [0.5, 0.5, 0.5])
        s.reverse()
        self.assertEqual(s[0].specie, Element("H"))
        self.assertArrayAlmostEqual(s[0].coords,
                                    [-0.513360, 0.889165, -0.363000])
        del s[1]
        self.assertEqual(s.formula, "H2 C1 F1")
        s[3] = "N", [0, 0, 0], {"charge": 4}
        self.assertEqual(s.formula, "H2 N1 F1")
        self.assertEqual(s[3].charge, 4)

    def test_insert_remove_append(self):
        mol = self.mol
        mol.insert(1, "O", [0.5, 0.5, 0.5])
        self.assertEqual(mol.formula, "H4 C1 O1")
        del mol[2]
        self.assertEqual(mol.formula, "H3 C1 O1")
        mol.set_charge_and_spin(0)
        self.assertEqual(mol.spin_multiplicity, 2)
        mol.append("N", [1, 1, 1])
        self.assertEqual(mol.formula, "H3 C1 N1 O1")
        self.assertRaises(TypeError, dict, [(mol, 1)])
        mol.remove_sites([0, 1])
        self.assertEqual(mol.formula, "H3 N1")

    def test_translate_sites(self):
        self.mol.translate_sites([0, 1], [0.5, 0.5, 0.5])
        self.assertArrayEqual(self.mol.cart_coords[0], [0.5, 0.5, 0.5])

    def test_rotate_sites(self):
        self.mol.rotate_sites(theta=np.radians(30))
        self.assertArrayAlmostEqual(self.mol.cart_coords[2],
                                    [0.889164737, 0.513359500, -0.363000000])

    def test_replace(self):
        self.mol[0] = "Ge"
        self.assertEqual(self.mol.formula, "Ge1 H4")

        self.mol.replace_species(
            {Element("Ge"): {
                 Element("Ge"): 0.5,
                 Element("Si"): 0.5
             }})
        self.assertEqual(self.mol.formula, "Si0.5 Ge0.5 H4")

        #this should change the .5Si .5Ge sites to .75Si .25Ge
        self.mol.replace_species(
            {Element("Ge"): {
                 Element("Ge"): 0.5,
                 Element("Si"): 0.5
             }})
        self.assertEqual(self.mol.formula, "Si0.75 Ge0.25 H4")

        d = 0.1
        pre_perturbation_sites = self.mol.sites[:]
        self.mol.perturb(distance=d)
        post_perturbation_sites = self.mol.sites

        for i, x in enumerate(pre_perturbation_sites):
            self.assertAlmostEqual(x.distance(post_perturbation_sites[i]), d,
                                   3, "Bad perturbation distance")

    def test_add_site_property(self):
        self.mol.add_site_property("charge", [4.1, -2, -2, -2, -2])
        self.assertEqual(self.mol[0].charge, 4.1)
        self.assertEqual(self.mol[1].charge, -2)

        self.mol.add_site_property("magmom", [3, 2, 2, 2, 2])
        self.assertEqual(self.mol[0].charge, 4.1)
        self.assertEqual(self.mol[0].magmom, 3)

    def test_to_from_dict(self):
        d = self.mol.as_dict()
        mol2 = Molecule.from_dict(d)
        self.assertEqual(type(mol2), Molecule)

    def test_apply_operation(self):
        op = SymmOp.from_axis_angle_and_translation([0, 0, 1], 90)
        self.mol.apply_operation(op)
        self.assertArrayAlmostEqual(self.mol[2].coords,
                                    [0.000000, 1.026719, -0.363000])

    def test_substitute(self):
        coords = [[0.000000, 0.000000, 1.08], [0.000000, 0.000000, 0.000000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        sub = Molecule(["X", "C", "H", "H", "H"], coords)
        self.mol.substitute(1, sub)
        self.assertAlmostEqual(self.mol.get_distance(0, 4), 1.54)
        f = Molecule(["X", "F"], [[0, 0, 0], [0, 0, 1.11]])
        self.mol.substitute(2, f)
        self.assertAlmostEqual(self.mol.get_distance(0, 7), 1.35)
        oh = Molecule(["X", "O", "H"],
                      [[0, 0.780362, -.456316], [0, 0, .114079],
                       [0, -.780362, -.456316]])
        self.mol.substitute(1, oh)
        self.assertAlmostEqual(self.mol.get_distance(0, 7), 1.43)
        self.mol.substitute(3, "methyl")
        self.assertEqual(self.mol.formula, "H7 C3 O1 F1")
        coords = [[0.00000, 1.40272, 0.00000], [0.00000, 2.49029, 0.00000],
                  [-1.21479, 0.70136, 0.00000], [-2.15666, 1.24515, 0.00000],
                  [-1.21479, -0.70136, 0.00000], [-2.15666, -1.24515, 0.00000],
                  [0.00000, -1.40272, 0.00000], [0.00000, -2.49029, 0.00000],
                  [1.21479, -0.70136, 0.00000], [2.15666, -1.24515, 0.00000],
                  [1.21479, 0.70136, 0.00000], [2.15666, 1.24515, 0.00000]]
        benzene = Molecule(
            ["C", "H", "C", "H", "C", "H", "C", "H", "C", "H", "C", "H"],
            coords)
        benzene.substitute(1, sub)
        self.assertEqual(benzene.formula, "H8 C7")
        # Carbon attached should be in plane.
        self.assertAlmostEqual(benzene[11].coords[2], 0)
        benzene[14] = "Br"
        benzene.substitute(13, sub)
        self.assertEqual(benzene.formula, "H9 C8 Br1")

    def test_to_from_file_string(self):
        for fmt in ["xyz", "json", "g03"]:
            s = self.mol.to(fmt=fmt)
            self.assertIsNotNone(s)
            m = Molecule.from_str(s, fmt=fmt)
            self.assertEqual(m, self.mol)
            self.assertIsInstance(m, Molecule)

        self.mol.to(filename="CH4_testing.xyz")
        self.assertTrue(os.path.exists("CH4_testing.xyz"))
        os.remove("CH4_testing.xyz")
コード例 #8
0
ファイル: io.py プロジェクト: gipfeli/PyXtal
class structure_from_ext():
    def __init__(self, struc, ref_mol=None, tol=0.2, relax_h=False):
        """
        extract the mol_site information from the give cif file 
        and reference molecule
    
        Args: 
            struc: cif/poscar file or a Pymatgen Structure object
            ref_mol: xyz file or a reference Pymatgen molecule object
            tol: scale factor for covalent bond distance
            relax_h: whether or not relax the position for hydrogen atoms in structure
        
    """
        if isinstance(ref_mol, str):
            ref_mol = Molecule.from_file(ref_mol)
        elif isinstance(ref_mol, Molecule):
            ref_mol = ref_mol
        else:
            print(type(ref_mol))
            raise NameError("reference molecule cannot be defined")

        if isinstance(struc, str):
            pmg_struc = Structure.from_file(struc)
        elif isinstance(struc, Structure):
            pmg_struc = struc
        else:
            print(type(struc))
            raise NameError("input structure cannot be intepretted")

        self.props = ref_mol.site_properties
        self.ref_mol = ref_mol.get_centered_molecule()
        self.tol = tol
        self.diag = False
        self.relax_h = relax_h

        sga = SpacegroupAnalyzer(pmg_struc)
        ops = sga.get_space_group_operations()
        self.wyc, perm = Wyckoff_position.from_symops(
            ops, sga.get_space_group_number())

        if self.wyc is not None:
            self.group = Group(self.wyc.number)
            if isinstance(perm, list):
                if perm != [0, 1, 2]:
                    lattice = Lattice.from_matrix(pmg_struc.lattice.matrix,
                                                  self.group.lattice_type)
                    latt = lattice.swap_axis(ids=perm,
                                             random=False).get_matrix()
                    coor = pmg_struc.frac_coords[:, perm]
                    pmg_struc = Structure(latt, pmg_struc.atomic_numbers, coor)
            else:
                self.diag = True
                self.perm = perm

            coords, numbers = search_molecule_in_crystal(pmg_struc, self.tol)
            #coords -= np.mean(coords, axis=0)
            if self.relax_h:
                self.molecule = self.addh(Molecule(numbers, coords))
            else:
                self.molecule = Molecule(numbers, coords)
            self.pmg_struc = pmg_struc
            self.lattice = Lattice.from_matrix(pmg_struc.lattice.matrix,
                                               self.group.lattice_type)
        else:
            raise ValueError(
                "Cannot find the space group matching the symmetry operation")

    def addh(self, mol):
        #if len(mol) < len(self.ref_mol):
        from pymatgen.io.babel import BabelMolAdaptor
        ad = BabelMolAdaptor(mol)
        ad.add_hydrogen()
        ad.localopt()
        mol = ad.pymatgen_mol
        return mol

    def add_site_props(self, mo):
        if len(self.props) > 0:
            for key in self.props.keys():
                mo.add_site_property(key, self.props[key])
        return mo

    def make_mol_site(self, ref=False):
        if ref:
            mol = self.ref_mol
            ori = self.ori
        else:
            mol = self.molecule
            ori = Orientation(np.eye(3))
        mol = self.add_site_props(mol)
        pmol = pyxtal_molecule(mol)
        site = mol_site(pmol, self.position, ori, self.wyc, self.lattice,
                        self.diag)
        return site

    def align(self):
        """
        compute the orientation wrt the reference molecule
        """
        try:
            from openbabel import pybel, openbabel
        except:
            import pybel, openbabel

        m1 = pybel.readstring('xyz', self.ref_mol.to('xyz'))
        m2 = pybel.readstring('xyz', self.molecule.to('xyz'))
        aligner = openbabel.OBAlign(True, False)
        aligner.SetRefMol(m1.OBMol)
        aligner.SetTargetMol(m2.OBMol)
        aligner.Align()
        print("RMSD: ", aligner.GetRMSD())
        rot = np.zeros([3, 3])
        for i in range(3):
            for j in range(3):
                rot[i, j] = aligner.GetRotMatrix().Get(i, j)
        coord2 = self.molecule.cart_coords
        coord2 -= np.mean(coord2, axis=0)
        coord3 = rot.dot(coord2.T).T + np.mean(self.ref_mol.cart_coords,
                                               axis=0)
        self.mol_aligned = Molecule(self.ref_mol.atomic_numbers, coord3)
        self.ori = Orientation(rot)

    def match(self):
        """
        Check the two molecular graphs are isomorphic
        """
        match, mapping = compare_mol_connectivity(self.ref_mol, self.molecule)
        if not match:
            print(self.ref_mol.to("xyz"))
            print(self.molecule.to("xyz"))
            import pickle
            with open('wrong.pkl', "wb") as f:
                pickle.dump([self.ref_mol, self.molecule], f)

            return False
        else:
            # resort the atomic number for molecule 1
            order = [mapping[i] for i in range(len(self.ref_mol))]
            numbers = np.array(self.molecule.atomic_numbers)
            numbers = numbers[order].tolist()
            coords = self.molecule.cart_coords[order]
            position = np.mean(coords, axis=0).dot(self.lattice.inv_matrix)
            position -= np.floor(position)
            # check if molecule is on the special wyckoff position
            if len(self.pmg_struc) / len(self.molecule) < len(self.wyc):
                if self.diag:
                    #Transform it to the conventional representation
                    position = np.dot(self.perm, position).T
                position, wp, _ = WP_merge(position, self.lattice.matrix,
                                           self.wyc, 2.0)
                #print("After Mergey:---------------")
                #print(position)
                #print(wp)
                self.wyc = wp
            self.position = position
            self.molecule = Molecule(numbers, coords - np.mean(coords, axis=0))
            #self.align()
            return True

    def show(self, overlay=True):
        from pyxtal.viz import display_molecules
        if overlay:
            return display_molecules([self.ref_mol, self.mol_aligned])
        else:
            return display_molecules([self.ref_mol, self.molecule])