def test_get_bonds(self): mol1 = Molecule.from_file(os.path.join(test_dir, "t1.xyz")) msc = MoleculeStructureComparator() # noinspection PyProtectedMember bonds = msc._get_bonds(mol1) bonds_ref = [(0, 1), (0, 2), (0, 3), (0, 23), (3, 4), (3, 5), (5, 6), (5, 7), (7, 8), (7, 9), (7, 21), (9, 10), (9, 11), (9, 12), (12, 13), (12, 14), (12, 15), (15, 16), (15, 17), (15, 18), (18, 19), (18, 20), (18, 21), (21, 22), (21, 23), (23, 24), (23, 25)] self.assertEqual(bonds, bonds_ref) mol2 = Molecule.from_file(os.path.join(test_dir, "MgBH42.xyz")) bonds = msc._get_bonds(mol2) self.assertEqual(bonds, [(1, 3), (2, 3), (3, 4), (3, 5), (6, 8), (7, 8), (8, 9), (8, 10)]) msc = MoleculeStructureComparator(ignore_ionic_bond=False) bonds = msc._get_bonds(mol2) self.assertEqual(bonds, [(0, 1), (0, 2), (0, 3), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 3), (2, 3), (3, 4), (3, 5), (6, 8), (7, 8), (8, 9), (8, 10)]) mol1 = Molecule.from_file(os.path.join(test_dir, "molecule_with_halogen_bonds_1.xyz")) msc = MoleculeStructureComparator() # noinspection PyProtectedMember bonds = msc._get_bonds(mol1) self.assertEqual(bonds, [(0, 12), (0, 13), (0, 14), (0, 15), (1, 12), (1, 16), (1, 17), (1, 18), (2, 4), (2, 11), (2, 19), (3, 5), (3, 10), (3, 20), (4, 6), (4, 10), (5, 11), (5, 12), (6, 7), (6, 8), (6, 9)])
def get_structures_from_trajectory(self): """ Convert the coordinates in each time step to a structure(boxed molecule). Used to construct DiffusionAnalyzer object. Returns: list of Structure objects """ structures = [] mass_to_symbol = dict( (round(y["Atomic mass"], 1), x) for x, y in _pt_data.items()) unique_atomic_masses = np.array(self.lammps_data.atomic_masses)[:, 1] for step in range(self.timesteps.size): begin = step * self.natoms end = (step + 1) * self.natoms mol_vector_structured = \ self.trajectory[begin:end][:][["x", "y", "z"]] new_shape = mol_vector_structured.shape + (-1,) mol_vector = mol_vector_structured.view(np.float64).reshape( new_shape) coords = mol_vector.copy() species = [mass_to_symbol[round(unique_atomic_masses[atype - 1], 1)] for atype in self.trajectory[begin:end][:]["atom_type"]] mol = Molecule(species, coords) try: boxed_mol = mol.get_boxed_structure(*self.box_lengths) except ValueError as error: print("Error: '{}' at timestep {} in the trajectory".format( error, int(self.timesteps[step]))) structures.append(boxed_mol) return structures
def test_assimilate_opt_with_hidden_changes_from_handler(self): drone = QChemDrone(additional_fields={"special_run_type": "frequency_flattener"}) doc = drone.assimilate( path=os.path.join(module_dir, "..", "test_files", "1746_complete"), input_file="mol.qin", output_file="mol.qout", multirun=False) self.assertEqual(doc["input"]["job_type"], "opt") self.assertEqual(doc["output"]["job_type"], "freq") self.assertEqual(doc["output"]["final_energy"], -303.835532370106) self.assertEqual(doc["smiles"], "O1C(=CC1=O)[CH]") self.assertEqual(doc["state"], "successful") self.assertEqual(doc["num_frequencies_flattened"], 0) self.assertEqual(doc["walltime"], 631.54) self.assertEqual(doc["cputime"], 7471.17) self.assertEqual(doc["formula_pretty"], "HC2O") self.assertEqual(doc["formula_anonymous"], "ABC2") self.assertEqual(doc["chemsys"], "C-H-O") self.assertEqual(doc["pointgroup"], "C1") self.assertEqual(doc["orig"]["rem"], doc["calcs_reversed"][-1]["input"]["rem"]) orig_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["orig"]["molecule"]), OpenBabelNN(), reorder=False, extend_structure=False) initial_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["input"]["initial_molecule"]), OpenBabelNN(), reorder=False, extend_structure=False) self.assertEqual(orig_molgraph.isomorphic_to(initial_molgraph), False)
def test_assimilate_unstable_opt(self): drone = QChemDrone( runs=[ "opt_0", "freq_0", "opt_1", "freq_1", "opt_2", "freq_2", "opt_3", "freq_3" ], additional_fields={"special_run_type": "frequency_flattener"}) doc = drone.assimilate( path=os.path.join(module_dir, "..", "test_files", "2620_complete"), input_file="mol.qin", output_file="mol.qout", multirun=False) self.assertEqual(doc["input"]["job_type"], "opt") self.assertEqual(doc["output"]["job_type"], "opt") self.assertEqual(doc["output"]["final_energy"], "unstable") self.assertEqual(doc["smiles"], "[S](=O)[N]S[C]") self.assertEqual(doc["state"], "unsuccessful") self.assertEqual(doc["num_frequencies_flattened"], 0) self.assertEqual(doc["walltime"], None) self.assertEqual(doc["cputime"], None) self.assertEqual(doc["formula_pretty"], "CS2NO") self.assertEqual(doc["formula_anonymous"], "ABCD2") self.assertEqual(doc["chemsys"], "C-N-O-S") self.assertEqual(doc["pointgroup"], "C1") self.assertEqual(doc["orig"]["rem"], doc["calcs_reversed"][-1]["input"]["rem"]) self.assertEqual(doc["orig"]["molecule"], doc["calcs_reversed"][-1]["input"]["molecule"]) orig_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["orig"]["molecule"]), OpenBabelNN(), reorder=False, extend_structure=False) initial_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["input"]["initial_molecule"]), OpenBabelNN(), reorder=False, extend_structure=False) self.assertEqual(orig_molgraph.isomorphic_to(initial_molgraph), True)
def test_get_centered_molecule(self): mol = Molecule(["O"] * 2, [[0, 0, 0], [0, 0, 1.2]], spin_multiplicity=3) centered = mol.get_centered_molecule() self.assertFalse(np.allclose(mol.center_of_mass, np.zeros(3), atol=1e-7)) self.assertTrue(np.allclose(centered.center_of_mass, np.zeros(3), atol=1e-7))
def setUpClass(cls): polymer_chain = Molecule.from_file(os.path.join(test_dir, "polymer_chain.xyz")) polymer_linear = Molecule.from_file(os.path.join(test_dir, "polymer_linear.xyz")) cls.polymer_matrix = Molecule.from_file(os.path.join(test_dir, "polymer_matrix.xyz")) charges = [-0.1187, 0.0861, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.1187, 0.0861, 0.0861, 0.0861] polymer_linear.add_site_property("charge", charges) topology = Topology.from_molecule(polymer_linear) cls.polymer_linear_ff_decorated = Molecule.from_file( os.path.join(test_dir,"polymer_linear.xyz")) ff_map = ['C2', 'H3', 'H2', 'H3', 'O', 'C3', 'H2', 'H3', 'C2', 'H3', 'H2', 'O', 'C2', 'H3', 'H2', 'C3', 'H2', 'H3', 'O', 'C3', 'H2', 'H3', 'C2', 'H3', 'H2', 'O', 'C2', 'H3', 'H2', 'C3', 'H2', 'H3', 'O', 'C3', 'H2', 'H3', 'C2', 'H3', 'H2', 'O', 'C2', 'H3', 'H2', 'C3', 'H2', 'H3', 'O', 'C3', 'H2', 'H3', 'H2'] cls.polymer_linear_ff_decorated.add_site_property("ff_map", ff_map) atoms = OrderedDict([("C", "C"), ("H", "H"), ("O", "O")]) bonds = OrderedDict([((u'C', u'O'), [1000, 1.4115]), ((u'C', u'H'), [1000, 1.1041]), ((u'C', u'C'), [1000, 1.5075])]) pairs = OrderedDict([((u'O', u'O'), [75844.8, 0.2461, 396.9]), ((u'H', u'H'), [2649.6, 0.2674, 27.22]), ((u'C', u'C'), [14976.0, 0.3236, 637.6])]) angles = OrderedDict([((u'C', u'C', u'H'), [42.9, 110.1]), ((u'H', u'C', u'H'), [38.5, 109.47]), ((u'H', u'C', u'O'), [56.0, 109.48]), ((u'C', u'C', u'O'), [86.0, 108.54]), ((u'C', u'O', u'C'), [74.5, 108.05])]) dihedrals = OrderedDict([((u'H', u'C', u'O', u'C'), [0.0, 0.0, -0.73, 0.0]), ((u'H', u'C', u'C', u'H'), [0.0, 0.0, 0.28, 0.0]), ((u'C', u'C', u'O', u'C'), [1.76, 0.67, 0.04, 0.0]), ((u'H', u'C', u'C', u'O'), [0.0, 0.0, 0.28, 0.0]), ((u'O', u'C', u'C', u'O'), [0.41, -2.1, -0.6, -0.82])]) forcefield = ForceField(atoms, bonds, angles, dihedrals=dihedrals, pairs=pairs) cls.molecules = [polymer_chain] * 3 cls.mols_number = [7, 3, 1] box_size = [[0.0, 50], [0.0, 50], [0.0, 50]] cls.topologies = [topology] * len(cls.molecules) cls.lammps_ff_data_1 = LammpsForceFieldData.from_forcefield_and_topology( cls.molecules, cls.mols_number, box_size, cls.polymer_matrix, forcefield, cls.topologies)
def __init__(self, structure, rmax=15, hkl_family=[(1, 0, 0), (1, 1, 1)], surface_energies=[28, 25] ): self.structure = structure self.rmax = rmax self.hkl_family = hkl_family self.surface_energies = surface_energies spherical_neighbors = self.structure.get_sites_in_sphere([0.0,0.0,0.0], self.rmax) recp_lattice = self.structure.lattice.reciprocal_lattice_crystallographic self.recp_lattice = recp_lattice.scale(1) self.set_miller_family() Molecule.__init__(self, [sn[0].species_and_occu for sn in spherical_neighbors], [sn[0].coords for sn in spherical_neighbors], charge=0)
def test_are_equal(self): msc1 = MoleculeStructureComparator() mol1 = Molecule.from_file(os.path.join(test_dir, "t1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t2.xyz")) mol3 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) self.assertFalse(msc1.are_equal(mol1, mol2)) self.assertTrue(msc1.are_equal(mol2, mol3)) thio1 = Molecule.from_file(os.path.join(test_dir, "thiophene1.xyz")) thio2 = Molecule.from_file(os.path.join(test_dir, "thiophene2.xyz")) # noinspection PyProtectedMember msc2 = MoleculeStructureComparator( priority_bonds=msc1._get_bonds(thio1)) self.assertTrue(msc2.are_equal(thio1, thio2))
def setUpClass(cls): cls.pc = Molecule.from_file( os.path.join(test_dir, "PC.xyz")) cls.pos_pc = Molecule.from_file( os.path.join(test_dir, "PC.xyz")) cls.pos_pc.set_charge_and_spin(charge=1) cls.pc_edges = [[5, 10], [5, 12], [5, 11], [5, 3], [3, 7], [3, 4], [3, 0], [4, 8], [4, 9], [4, 1], [6, 1], [6, 0], [6, 2]] cls.pc_frag1 = Molecule.from_file( os.path.join(test_dir, "PC_frag1.xyz")) cls.pc_frag1_edges = [[0, 2], [4, 2], [2, 1], [1, 3]] cls.tfsi = Molecule.from_file(os.path.join(test_dir, "TFSI.xyz")) cls.tfsi_edges = [14,1],[1,4],[1,5],[1,7],[7,11],[7,12],[7,13],[14,0],[0,2],[0,3],[0,6],[6,8],[6,9],[6,10]
def setUp(self): cyclohexene = Molecule.from_file(os.path.join(os.path.dirname(__file__), "..", "..", "..", "test_files/graphs/cyclohexene.xyz")) self.cyclohexene = MoleculeGraph.with_empty_graph(cyclohexene, edge_weight_name="strength", edge_weight_units="") self.cyclohexene.add_edge(0, 1, weight=1.0) self.cyclohexene.add_edge(1, 2, weight=1.0) self.cyclohexene.add_edge(2, 3, weight=2.0) self.cyclohexene.add_edge(3, 4, weight=1.0) self.cyclohexene.add_edge(4, 5, weight=1.0) self.cyclohexene.add_edge(5, 0, weight=1.0) self.cyclohexene.add_edge(0, 6, weight=1.0) self.cyclohexene.add_edge(0, 7, weight=1.0) self.cyclohexene.add_edge(1, 8, weight=1.0) self.cyclohexene.add_edge(1, 9, weight=1.0) self.cyclohexene.add_edge(2, 10, weight=1.0) self.cyclohexene.add_edge(3, 11, weight=1.0) self.cyclohexene.add_edge(4, 12, weight=1.0) self.cyclohexene.add_edge(4, 13, weight=1.0) self.cyclohexene.add_edge(5, 14, weight=1.0) self.cyclohexene.add_edge(5, 15, weight=1.0) butadiene = Molecule.from_file(os.path.join(os.path.dirname(__file__), "..", "..", "..", "test_files/graphs/butadiene.xyz")) self.butadiene = MoleculeGraph.with_empty_graph(butadiene, edge_weight_name="strength", edge_weight_units="") self.butadiene.add_edge(0, 1, weight=2.0) self.butadiene.add_edge(1, 2, weight=1.0) self.butadiene.add_edge(2, 3, weight=2.0) self.butadiene.add_edge(0, 4, weight=1.0) self.butadiene.add_edge(0, 5, weight=1.0) self.butadiene.add_edge(1, 6, weight=1.0) self.butadiene.add_edge(2, 7, weight=1.0) self.butadiene.add_edge(3, 8, weight=1.0) self.butadiene.add_edge(3, 9, weight=1.0) ethylene = Molecule.from_file(os.path.join(os.path.dirname(__file__), "..", "..", "..", "test_files/graphs/ethylene.xyz")) self.ethylene = MoleculeGraph.with_empty_graph(ethylene, edge_weight_name="strength", edge_weight_units="") self.ethylene.add_edge(0, 1, weight=2.0) self.ethylene.add_edge(0, 2, weight=1.0) self.ethylene.add_edge(0, 3, weight=1.0) self.ethylene.add_edge(1, 4, weight=1.0) self.ethylene.add_edge(1, 5, weight=1.0) warnings.simplefilter("ignore")
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 setUp(self): self.polymer_linear = Molecule.from_file( os.path.join(test_dir, "polymer_linear.xyz")) charges = [-0.1187, 0.0861, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861, -0.0326, 0.0861, 0.0861, -0.2792, -0.1187, 0.0861, 0.0861, 0.0861] ff_map = ["C3", "H3", "H3", "H3", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C2", "H2", "H2", "C2", "H2", "H2", "O", "C3", "H3", "H3", "H3"] self.polymer_linear.add_site_property("charge", charges) self.polymer_linear.add_site_property("ff_map", ff_map) self.topology = Topology.from_molecule(self.polymer_linear) self.forcefield = ForceField.from_file( os.path.join(test_dir, "ffmap_data.yaml")) box_size = [[0.0, 50], [0.0, 50], [0.0, 50]] self.lammps_ff_data = LammpsForceFieldData.from_forcefield_and_topology( [self.polymer_linear], [1], box_size, self.polymer_linear, self.forcefield, [self.topology])
def from_dict(cls, d): return FiestaInput(Molecule.from_dict(d["mol"]), correlation_grid=d["correlation_grid"], Exc_DFT_option=d["Exc_DFT_option"], COHSEX_options=d["geometry_options"], GW_options=d["symmetry_options"], BSE_TDDFT_options=d["memory_options"])
def get_boxed_molecule(input_structure, box_size): """ Return a boxed molecule. Args: input_structure(Molecule/Structure): either Molecule of Structure object box_size (list): [[x_min, x_max], [y_min, y_max], [z_min, z_max]] Returns: Structure """ box_lengths = [min_max[1] - min_max[0] for min_max in box_size] # be defensive about the box size if isinstance(input_structure, Molecule): boxed_molecule = input_structure.get_boxed_structure(*box_lengths) elif isinstance(input_structure, Structure): max_length = max(input_structure.lattice.abc) max_box_size = max(box_lengths) boxed_molecule = Molecule.from_sites(input_structure.sites) if max_length < max_box_size: boxed_molecule = \ boxed_molecule.get_boxed_structure(*box_lengths) else: boxed_molecule = \ boxed_molecule.get_boxed_structure(max_length, max_length, max_length) else: raise ValueError("molecule must be an object of Molecule or " "Structure ") return boxed_molecule
def test_isomorphic_to(self): ethylene = Molecule.from_file( os.path.join( os.path.dirname(__file__), "..", "..", "..", "test_files/graphs/ethylene.xyz", ) ) # switch carbons ethylene[0], ethylene[1] = ethylene[1], ethylene[0] eth_copy = MoleculeGraph.with_edges( ethylene, { (0, 1): {"weight": 2}, (1, 2): {"weight": 1}, (1, 3): {"weight": 1}, (0, 4): {"weight": 1}, (0, 5): {"weight": 1}, }, ) # If they are equal, they must also be isomorphic eth_copy = copy.deepcopy(self.ethylene) self.assertTrue(self.ethylene.isomorphic_to(eth_copy)) self.assertFalse(self.butadiene.isomorphic_to(self.ethylene))
def from_dict(cls, d): return NwInput(Molecule.from_dict(d["mol"]), tasks=[NwTask.from_dict(dt) for dt in d["tasks"]], directives=[tuple(li) for li in d["directives"]], geometry_options=d["geometry_options"], symmetry_options=d["symmetry_options"], memory_options=d["memory_options"])
def from_structure(cls, input_structure, box_size, set_charge=True, translate=True): """ Set LammpsData from the given structure. If the input structure is a Structure, it is converted to a molecule. TIf the molecule doesnt fit in the input box, the box size is updated based on the max and min site coordinates of the molecules. Args: input_structure (Molecule/Structure) box_size (list): [[x_min, x_max], [y_min, y_max], [z_min, z_max]] set_charge (bool): whether or not to set the charge field in Atoms. If true, the charge will be non-zero only if the input_structure has the "charge" site property set. translate (bool): if true move the molecule to the center of the new box(it that is required). Returns: LammpsData """ if isinstance(input_structure, Structure): input_structure = Molecule.from_sites(input_structure.sites) box_size = cls.check_box_size(input_structure, box_size, translate=translate) natoms, natom_types, atomic_masses_dict = cls.get_basic_system_info(input_structure.copy()) atoms_data = cls.get_atoms_data(input_structure, atomic_masses_dict, set_charge=set_charge) return cls(box_size, atomic_masses_dict.values(), atoms_data)
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_main(self): o = Molecule.from_str(rhb18xyz, "xyz") o.set_charge_and_spin(-1, 3) task = AdfTask("optimize", **rhb18) inp = AdfInput(task) inp.write_file(o, self.tempfile) s = readfile(join(test_dir, "adf", "RhB18_adf.inp")) self.assertEqual(readfile(self.tempfile), s)
def __init__(self, mols, cm_dist=[], angle={}, link={}, remove=[], charge=0, spin_multiplicity=None, validate_proximity=False): Molecule.__init__(self, mols[0].species_and_occu, mols[0].cart_coords, charge=charge, spin_multiplicity=spin_multiplicity, validate_proximity=validate_proximity, site_properties=mols[0].site_properties) self._sites = list(self._sites) self.mols = mols self.cm_dist = cm_dist self.angle = angle self.link = link self.remove = remove if len(self.mols) == 1: self.set_distance_matrix(self.mols[0])
def setUp(self): warnings.simplefilter("ignore") self.file = os.path.join(test_dir, "func_group_test.mol") self.mol = Molecule.from_file(self.file) self.strat = OpenBabelNN() self.mg = MoleculeGraph.with_local_env_strategy(self.mol, self.strat, reorder=False, extend_structure=False) self.extractor = FunctionalGroupExtractor(self.mg)
def test_to_from_dict(self): propertied_mol = Molecule(["C", "H", "H", "H", "H"], self.coords, site_properties={'magmom': [0.5, -0.5, 1, 2, 3]}) d = propertied_mol.to_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")
def test_spherical(self): a = PointGroupAnalyzer(CH4) self.assertEqual(a.sch_symbol, "Td") self.assertEqual(len(a.get_pointgroup()), 24) a = PointGroupAnalyzer(PF6) self.assertEqual(a.sch_symbol, "Oh") self.assertEqual(len(a.get_pointgroup()), 48) m = Molecule.from_file(os.path.join(test_dir_mol, "c60.xyz")) a = PointGroupAnalyzer(m) self.assertEqual(a.sch_symbol, "Ih")
def test_dihedral(self): a = PointGroupAnalyzer(C2H4) self.assertEqual(a.sch_symbol, "D2h") self.assertEqual(len(a.get_pointgroup()), 8) a = PointGroupAnalyzer(BF3) self.assertEqual(a.sch_symbol, "D3h") self.assertEqual(len(a.get_pointgroup()), 12) m = Molecule.from_file(os.path.join(test_dir_mol, "b12h12.xyz")) a = PointGroupAnalyzer(m) self.assertEqual(a.sch_symbol, "D5d")
def __init__(self, structure, rmax=15, hkl_family=[(1,0,0), (1,1,1)], surface_energies=[28,25], scell=None): self.structure = structure self.rmax = rmax self.hkl_family = hkl_family self.surface_energies = surface_energies if scell is None: ncella = int(np.ceil(2*rmax/structure.lattice.a)) ncellb = int(np.ceil(2*rmax/structure.lattice.b)) ncellc = int(np.ceil(2*rmax/structure.lattice.c)) self.scell = [ncella, ncellb, ncellc] else: self.scell = scell self.structure.make_supercell(self.scell) recp_lattice = self.structure.lattice.reciprocal_lattice_crystallographic self.recp_lattice = recp_lattice.scale(1) self.set_miller_family() Molecule.__init__(self, [site.species_and_occu for site in self.structure.sites], self.structure.cart_coords, charge=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")
def test_group_molecules(self): mm = MoleculeMatcher(tolerance=0.001) with open(os.path.join(test_dir, "mol_list.txt")) as f: filename_list = [line.strip() for line in f.readlines()] mol_list = [Molecule.from_file(os.path.join(test_dir, f)) for f in filename_list] mol_groups = mm.group_molecules(mol_list) filename_groups = [[filename_list[mol_list.index(m)] for m in g] for g in mol_groups] with open(os.path.join(test_dir, "grouped_mol_list.txt")) as f: grouped_text = f.read().strip() self.assertEqual(str(filename_groups), grouped_text)
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 boxed_molecule(cls, pseudos, cart_coords, acell=3*(10,)): """ Creates a molecule in a periodic box of lengths acell [Bohr] Args: pseudos: List of pseudopotentials cart_coords: Cartesian coordinates acell: Lengths of the box in *Bohr* """ cart_coords = np.atleast_2d(cart_coords) molecule = Molecule([p.symbol for p in pseudos], cart_coords) l = Bohr2Ang(acell) structure = molecule.get_boxed_structure(l[0], l[1], l[2]) return cls(structure)
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 setUpClass(cls): cls.mol1 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster.xyz")) cls.mm = HungarianOrderMatcher(cls.mol1)
def test_missmatched_atoms(self): mol2 = Molecule.from_file(os.path.join(test_dir, "Si_cluster.xyz")) with self.assertRaises(ValueError): res = self.mm.fit(mol2)
def test_to_from_dict(self): d = self.mol.to_dict mol2 = Molecule.from_dict(d) self.assertEqual(type(mol2), Molecule)
def setUpClass(cls): cls.mol1 = Molecule.from_file(os.path.join(test_dir, "Si_cluster.xyz")) cls.mm = BruteForceOrderMatcher(cls.mol1)
def test_perturbed_atom_position(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster_perturbed.xyz")) res = self.mm.fit(mol2) self.assertEqual(len(res), 3) self.assertAlmostEqual(res[0][1], 0.24340452336622473, places=6)
def __init__(self, molecule, optimize=False): """ Instantiation method for FunctionalGroupExtractor. :param molecule: Either a filename, a pymatgen.core.structure.Molecule object, or a pymatgen.analysis.graphs.MoleculeGraph object. :param optimize: Default False. If True, then the input molecule will be modified, adding Hydrogens, performing a simple conformer search, etc. """ self.molgraph = None if isinstance(molecule, str): try: if optimize: obmol = BabelMolAdaptor.from_file(molecule, file_format="mol") # OBMolecule does not contain pymatgen Molecule information # So, we need to wrap the obmol in a BabelMolAdapter obmol.add_hydrogen() obmol.make3d() obmol.localopt() self.molecule = obmol.pymatgen_mol else: self.molecule = Molecule.from_file(molecule) except OSError: raise ValueError("Input must be a valid molecule file, a " "Molecule object, or a MoleculeGraph object.") elif isinstance(molecule, Molecule): if optimize: obmol = BabelMolAdaptor(molecule) obmol.add_hydrogen() obmol.make3d() obmol.localopt() self.molecule = obmol.pymatgen_mol else: self.molecule = molecule elif isinstance(molecule, MoleculeGraph): if optimize: obmol = BabelMolAdaptor(molecule.molecule) obmol.add_hydrogen() obmol.make3d() obmol.localopt() self.molecule = obmol.pymatgen_mol else: self.molecule = molecule.molecule self.molgraph = molecule else: raise ValueError("Input to FunctionalGroupExtractor must be" "str, Molecule, or MoleculeGraph.") if self.molgraph is None: self.molgraph = MoleculeGraph.with_local_env_strategy( self.molecule, OpenBabelNN()) # Assign a specie and coordinates to each node in the graph, # corresponding to the Site in the Molecule object self.molgraph.set_node_attributes() self.species = nx.get_node_attributes(self.molgraph.graph, "specie")
def test_random_match(self): mol2 = Molecule.from_file(os.path.join(test_dir, "Si2O_cluster_2.xyz")) _, rmsd = self.mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.23231038877573124, places=6)
def test_fit(self): mol1 = Molecule.from_file(os.path.join(test_dir, "benzene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "benzene2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 1.4171601659148593e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "c1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "c2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 9.479012116064961e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t4.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.002825344731118855, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "j1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "j2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 9.28245597473488e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "ethene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "ethene2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.00021150729609276233, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "toluene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "toluene2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.0001445787263551832, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "cyclohexane1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "cyclohexane2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.00012447269440740117, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "oxygen1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "oxygen2.xyz")) mm = HungarianOrderMatcher(mol1) _, rmsd = mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.0, places=6)
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 = """Molecule Summary (H4 C1) Reduced Formula: H4C Charge = 0, Spin Mult = 1 Sites (5) 1 C 0.000000 0.000000 0.000000 2 H 0.000000 0.000000 1.089000 3 H 1.026719 0.000000 -0.363000 4 H -0.513360 -0.889165 -0.363000 5 H -0.513360 0.889165 -0.363000""" self.assertEqual(str(self.mol), 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_to_from_dict(self): propertied_mol = Molecule( ["C", "H", "H", "H", "H"], self.coords, site_properties={'magmom': [0.5, -0.5, 1, 2, 3]}) d = propertied_mol.to_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") def test_get_boxed_structure(self): s = self.mol.get_boxed_structure(9, 9, 9) self.assertArrayAlmostEqual(s[1].frac_coords, [0.0, 0.0, 0.121]) self.assertRaises(ValueError, self.mol.get_boxed_structure, 1, 1, 1) 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], 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.to_dict mol2 = IMolecule.from_dict(d) self.assertEqual(type(mol2), IMolecule)
def test_permuted_atoms_order(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster_permuted.xyz")) res = self.mm.fit(mol2) self.assertEqual(len(res), 3) self.assertAlmostEqual(res[0][1], 0.0, places=6)
def test_tricky(self): m = Molecule.from_file(test_dir_mol / "dh.xyz") a = PointGroupAnalyzer(m, 0.1) self.assertEqual(a.sch_symbol, "D*h")
def test_perturbed_atom_position(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster_perturbed.xyz")) _, rmsd = self.mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.24474957657894614, places=6)
def test_random_match(self): mol2 = Molecule.from_file(os.path.join(test_dir, "Si_cluster_2.xyz")) res = self.mm.fit(mol2) self.assertAlmostEqual(res[0][-1], 0.22163169511782, places=6)
def test_random_match(self): # TODO: Checking the cause of the large deviation mol2 = Molecule.from_file(os.path.join(test_dir, "Si_cluster_2.xyz")) _, rmsd = self.mm.fit(mol2) self.assertAlmostEqual(rmsd, 1.0177241485450828, places=6)
def test_perturbed_atom_position(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si_cluster_perturbed.xyz")) res = self.mm.fit(mol2) self.assertAlmostEqual(res[0][-1], 0.2232223954240079, places=6)
def test_rotated_molecule(self): # TODO: Checking the cause of the large deviation mol2 = Molecule.from_file( os.path.join(test_dir, "Si_cluster_rotated.xyz")) _, rmsd = self.mm.fit(mol2) self.assertAlmostEqual(rmsd, 1.025066171481399, places=6)
def setUpClass(cls): cls.mol1 = Molecule.from_file(os.path.join(test_dir, "Si_cluster.xyz")) cls.mm = KabschMatcher(cls.mol1)
def test_rotated_molecule(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster_rotated.xyz")) res = self.mm.fit(mol2) self.assertAlmostEqual(res[0][1], 0.0, places=6)
def test_permuted_atoms_order(self): mol2 = Molecule.from_file( os.path.join(test_dir, "Si_cluster_permuted.xyz")) _, rmsd = self.mm.fit(mol2) self.assertAlmostEqual(rmsd, 0.0, places=6)
def test_strange_inchi(self): mm = MoleculeMatcher(tolerance=0.05, mapper=InchiMolAtomMapper()) mol1 = Molecule.from_file(os.path.join(test_dir, "k1.sdf")) mol2 = Molecule.from_file(os.path.join(test_dir, "k2.sdf")) self.assertTrue(mm.fit(mol1, mol2))
def test_random_match(self): mol2 = Molecule.from_file(os.path.join(test_dir, "Si_cluster_2.xyz")) # ValueError: The number of all possible permuataions (20922789888000) is not feasible to run this method! with self.assertRaises(ValueError): _, rmsd = self.mm.fit(mol2)
def fit_with_mapper(self, mapper): 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], ] mol1 = Molecule(["C", "H", "H", "H", "H"], coords) op = SymmOp.from_origin_axis_angle([0, 0, 0], [0.1, 0.2, 0.3], 60) rotcoords = [op.operate(c) for c in coords] mol2 = Molecule(["C", "H", "H", "H", "H"], rotcoords) mm = MoleculeMatcher(mapper=mapper) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "benzene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "benzene2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "benzene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t2.xyz")) self.assertFalse(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "c1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "c2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t4.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "j1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "j2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "ethene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "ethene2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "toluene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "toluene2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "cyclohexane1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "cyclohexane2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mol1 = Molecule.from_file(os.path.join(test_dir, "oxygen1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "oxygen2.xyz")) self.assertTrue(mm.fit(mol1, mol2)) mm = MoleculeMatcher(tolerance=0.001, mapper=mapper) mol1 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t4.xyz")) self.assertFalse(mm.fit(mol1, mol2))
def test_get_rmsd(self): mm = MoleculeMatcher() mol1 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t4.xyz")) self.assertEqual(f"{mm.get_rmsd(mol1, mol2):7.3}", "0.00488")
from pymatgen.core.structure import Molecule from pymatgen.symmetry.pointgroup import PointGroupAnalyzer, cluster_sites from pymatgen.io.xyzio import XYZ from pymatgen.io.smartio import read_mol try: import scipy except ImportError: scipy = None test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", 'test_files', "molecules") H2O2 = Molecule( ["O", "O", "H", "H"], [[0, 0.727403, -0.050147], [0, -0.727403, -0.050147], [0.83459, 0.897642, 0.401175], [-0.83459, -0.897642, 0.401175]]) C2H2F2Br2 = Molecule( ["C", "C", "F", "Br", "H", "F", "H", "Br"], [[-0.752000, 0.001000, -0.141000], [0.752000, -0.001000, 0.141000], [-1.158000, 0.991000, 0.070000], [-1.240000, -0.737000, 0.496000], [-0.924000, -0.249000, -1.188000], [1.158000, -0.991000, -0.070000], [0.924000, 0.249000, 1.188000], [1.240000, 0.737000, -0.496000]]) H2O = Molecule( ["H", "O", "H"], [[0, 0.780362, -.456316], [0, 0, .114079], [0, -.780362, -.456316]]) C2H4 = Molecule(["C", "C", "H", "H", "H", "H"], [[0.0000, 0.0000, 0.6695], [0.0000, 0.0000, -0.6695],
def test_cdi_23(self): mm = MoleculeMatcher(tolerance=0.05, mapper=InchiMolAtomMapper()) mol1 = Molecule.from_file(os.path.join(test_dir, "cdi_23_1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "cdi_23_2.xyz")) self.assertFalse(mm.fit(mol1, mol2))
def setUpClass(cls): cls.mol1 = Molecule.from_file( os.path.join(test_dir, "Si2O_cluster.xyz")) cls.mm = GeneticOrderMatcher(cls.mol1, threshold=0.3)
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_insert_remove_append(self): mol = self.mol mol.insert(1, "O", [0.5, 0.5, 0.5]) self.assertEqual(mol.formula, "H4 C1 O1") mol.remove(2) self.assertEqual(mol.formula, "H3 C1 O1") mol.set_charge_and_spin(0) self.assertEqual(mol.spin_multiplicity, 2) mol.append("N", [0.25, 0.25, 0.25]) 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.replace(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.to_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) sub = Molecule(["X", "F"], [[0, 0, 0], [0, 0, 1.11]]) self.mol.substitute(2, sub) 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)
def test_thiane(self): mm = MoleculeMatcher(tolerance=0.05, mapper=InchiMolAtomMapper()) mol1 = Molecule.from_file(os.path.join(test_dir, "thiane1.sdf")) mol2 = Molecule.from_file(os.path.join(test_dir, "thiane2.sdf")) self.assertFalse(mm.fit(mol1, mol2))
def _parse_job(output): energy_patt = re.compile(r"Total \w+ energy\s+=\s+([.\-\d]+)") energy_gas_patt = re.compile(r"gas phase energy\s+=\s+([.\-\d]+)") energy_sol_patt = re.compile(r"sol phase energy\s+=\s+([.\-\d]+)") coord_patt = re.compile(r"\d+\s+(\w+)\s+[.\-\d]+\s+([.\-\d]+)\s+" r"([.\-\d]+)\s+([.\-\d]+)") lat_vector_patt = re.compile(r"a[123]=<\s+([.\-\d]+)\s+" r"([.\-\d]+)\s+([.\-\d]+)\s+>") corrections_patt = re.compile(r"([\w\-]+ correction to \w+)\s+=" r"\s+([.\-\d]+)") preamble_patt = re.compile(r"(No. of atoms|No. of electrons" r"|SCF calculation type|Charge|Spin " r"multiplicity)\s*:\s*(\S+)") force_patt = re.compile(r"\s+(\d+)\s+(\w+)" + 6 * r"\s+([0-9\.\-]+)") time_patt = re.compile( r"\s+ Task \s+ times \s+ cpu: \s+ ([.\d]+)s .+ ", re.VERBOSE) error_defs = { "calculations not reaching convergence": "Bad convergence", "Calculation failed to converge": "Bad convergence", "geom_binvr: #indep variables incorrect": "autoz error", "dft optimize failed": "Geometry optimization failed", } def fort2py(x): return x.replace("D", "e") def isfloatstring(s): return s.find(".") == -1 parse_hess = False parse_proj_hess = False hessian = None projected_hessian = None parse_force = False all_forces = [] forces = [] data = {} energies = [] frequencies = None normal_frequencies = None corrections = {} molecules = [] structures = [] species = [] coords = [] lattice = [] errors = [] basis_set = {} bset_header = [] parse_geom = False parse_freq = False parse_bset = False parse_projected_freq = False job_type = "" parse_time = False time = 0 for l in output.split("\n"): # pylint: disable=E1136 for e, v in error_defs.items(): if l.find(e) != -1: errors.append(v) if parse_time: m = time_patt.search(l) if m: time = m.group(1) parse_time = False if parse_geom: if l.strip() == "Atomic Mass": if lattice: structures.append( Structure(lattice, species, coords, coords_are_cartesian=True)) else: molecules.append(Molecule(species, coords)) species = [] coords = [] lattice = [] parse_geom = False else: m = coord_patt.search(l) if m: species.append(m.group(1).capitalize()) coords.append([ float(m.group(2)), float(m.group(3)), float(m.group(4)) ]) m = lat_vector_patt.search(l) if m: lattice.append([ float(m.group(1)), float(m.group(2)), float(m.group(3)) ]) if parse_force: m = force_patt.search(l) if m: forces.extend(map(float, m.groups()[5:])) elif len(forces) > 0: all_forces.append(forces) forces = [] parse_force = False elif parse_freq: if len(l.strip()) == 0: if len(normal_frequencies[-1][1]) == 0: continue parse_freq = False else: vibs = [float(vib) for vib in l.strip().split()[1:]] num_vibs = len(vibs) for mode, dis in zip(normal_frequencies[-num_vibs:], vibs): mode[1].append(dis) elif parse_projected_freq: if len(l.strip()) == 0: if len(frequencies[-1][1]) == 0: continue parse_projected_freq = False else: vibs = [float(vib) for vib in l.strip().split()[1:]] num_vibs = len(vibs) for mode, dis in zip(frequencies[-num_vibs:], vibs): mode[1].append(dis) elif parse_bset: if l.strip() == "": parse_bset = False else: toks = l.split() if toks[0] != "Tag" and not re.match(r"-+", toks[0]): basis_set[toks[0]] = dict( zip(bset_header[1:], toks[1:])) elif toks[0] == "Tag": bset_header = toks bset_header.pop(4) bset_header = [h.lower() for h in bset_header] elif parse_hess: if l.strip() == "": continue if len(hessian) > 0 and l.find("----------") != -1: parse_hess = False continue toks = l.strip().split() if len(toks) > 1: try: row = int(toks[0]) except Exception: continue if isfloatstring(toks[1]): continue vals = [float(fort2py(x)) for x in toks[1:]] if len(hessian) < row: hessian.append(vals) else: hessian[row - 1].extend(vals) elif parse_proj_hess: if l.strip() == "": continue nat3 = len(hessian) toks = l.strip().split() if len(toks) > 1: try: row = int(toks[0]) except Exception: continue if isfloatstring(toks[1]): continue vals = [float(fort2py(x)) for x in toks[1:]] if len(projected_hessian) < row: projected_hessian.append(vals) else: projected_hessian[row - 1].extend(vals) if len(projected_hessian[-1]) == nat3: parse_proj_hess = False else: m = energy_patt.search(l) if m: energies.append(Energy(m.group(1), "Ha").to("eV")) parse_time = True continue m = energy_gas_patt.search(l) if m: cosmo_scf_energy = energies[-1] energies[-1] = {} energies[-1].update({"cosmo scf": cosmo_scf_energy}) energies[-1].update( {"gas phase": Energy(m.group(1), "Ha").to("eV")}) m = energy_sol_patt.search(l) if m: energies[-1].update( {"sol phase": Energy(m.group(1), "Ha").to("eV")}) m = preamble_patt.search(l) if m: try: val = int(m.group(2)) except ValueError: val = m.group(2) k = m.group(1).replace("No. of ", "n").replace(" ", "_") data[k.lower()] = val elif l.find('Geometry "geometry"') != -1: parse_geom = True elif l.find('Summary of "ao basis"') != -1: parse_bset = True elif l.find("P.Frequency") != -1: parse_projected_freq = True if frequencies is None: frequencies = [] toks = l.strip().split()[1:] frequencies.extend([(float(freq), []) for freq in toks]) elif l.find("Frequency") != -1: toks = l.strip().split() if len(toks) > 1 and toks[0] == "Frequency": parse_freq = True if normal_frequencies is None: normal_frequencies = [] normal_frequencies.extend([ (float(freq), []) for freq in l.strip().split()[1:] ]) elif l.find("MASS-WEIGHTED NUCLEAR HESSIAN") != -1: parse_hess = True if not hessian: hessian = [] elif l.find("MASS-WEIGHTED PROJECTED HESSIAN") != -1: parse_proj_hess = True if not projected_hessian: projected_hessian = [] elif l.find( "atom coordinates gradient" ) != -1: parse_force = True elif job_type == "" and l.strip().startswith("NWChem"): job_type = l.strip() if job_type == "NWChem DFT Module" and "COSMO solvation results" in output: job_type += " COSMO" else: m = corrections_patt.search(l) if m: corrections[m.group(1)] = FloatWithUnit( m.group(2), "kJ mol^-1").to("eV atom^-1") if frequencies: for freq, mode in frequencies: mode[:] = zip(*[iter(mode)] * 3) if normal_frequencies: for freq, mode in normal_frequencies: mode[:] = zip(*[iter(mode)] * 3) if hessian: n = len(hessian) for i in range(n): for j in range(i + 1, n): hessian[i].append(hessian[j][i]) if projected_hessian: n = len(projected_hessian) for i in range(n): for j in range(i + 1, n): projected_hessian[i].append(projected_hessian[j][i]) data.update({ "job_type": job_type, "energies": energies, "corrections": corrections, "molecules": molecules, "structures": structures, "basis_set": basis_set, "errors": errors, "has_error": len(errors) > 0, "frequencies": frequencies, "normal_frequencies": normal_frequencies, "hessian": hessian, "projected_hessian": projected_hessian, "forces": all_forces, "task_time": time, }) return data
def test_fit(self): mol1 = Molecule.from_file(os.path.join(test_dir, "benzene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "benzene2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 7.061017534055039e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "c1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "c2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 9.459575146593829e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "t3.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "t4.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 0.0028172956033734615, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "j1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "j2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 9.28245597473488e-05, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "ethene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "ethene2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 0.00019757961816426042, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "toluene1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "toluene2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.1) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 0.0001398867874149986, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "cyclohexane1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "cyclohexane2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 0.00012190586696474853, places=6) mol1 = Molecule.from_file(os.path.join(test_dir, "oxygen1.xyz")) mol2 = Molecule.from_file(os.path.join(test_dir, "oxygen2.xyz")) mm = GeneticOrderMatcher(mol1, threshold=0.01) _, rmsd = mm.fit(mol2)[0] self.assertAlmostEqual(rmsd, 0.0, places=6)