def from_ob_mol(mol, obmol, raise_atomtype_exception=True): """ Convert a OpenBabel Mol object `obmol` to a molecular structure. Uses `OpenBabel <http://openbabel.org/>`_ to perform the conversion. """ # Below are the declared variables for cythonizing the module # cython.declare(i=cython.int) # cython.declare(radical_electrons=cython.int, charge=cython.int, lone_pairs=cython.int) # cython.declare(atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond) if openbabel is None: raise DependencyError( 'OpenBabel is not installed. Please install or use RDKit.') mol.vertices = [] # Add hydrogen atoms to complete molecule if needed obmol.AddHydrogens() # TODO Chem.rdmolops.Kekulize(obmol, clearAromaticFlags=True) # iterate through atoms in obmol for obatom in openbabel.OBMolAtomIter(obmol): # Use atomic number as key for element number = obatom.GetAtomicNum() isotope = obatom.GetIsotope() element = elements.get_element(number, isotope or -1) # Process charge charge = obatom.GetFormalCharge() obatom_multiplicity = obatom.GetSpinMultiplicity() radical_electrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0 atom = mm.Atom(element, radical_electrons, charge, '', 0) mol.vertices.append(atom) # iterate through bonds in obmol for obbond in openbabel.OBMolBondIter(obmol): # Process bond type oborder = obbond.GetBondOrder() if oborder not in [1, 2, 3, 4] and obbond.IsAromatic(): oborder = 1.5 bond = mm.Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1], mol.vertices[obbond.GetEndAtomIdx() - 1], oborder) # python array indices start at 0 mol.add_bond(bond) # Set atom types and connectivity values mol.update_connectivity_values() mol.update_atomtypes(log_species=True, raise_exception=raise_atomtype_exception) mol.update_multiplicity() mol.identify_ring_membership() # Assume this is always true # There are cases where 2 radical_electrons is a singlet, but # the triplet is often more stable, mol.multiplicity = mol.get_radical_count() + 1 return mol
def to_rmg_mol(self): if self.rmg_mol is not None: return self.rmg_mol import rmgpy.molecule.molecule as rmg_molecule rmg_atoms = [rmg_molecule.Atom(element=atom.symbol, coords=atom.coords) for atom in self] mapping = {atom: rmg_atom for atom, rmg_atom in zip(self.atoms, rmg_atoms)} rmg_bonds = [rmg_molecule.Bond(mapping[connection.atom1], mapping[connection.atom2]) for connection in self.get_all_connections()] rmg_mol = rmg_molecule.Molecule(atoms=rmg_atoms) for bond in rmg_bonds: rmg_mol.add_bond(bond) self.rmg_mol = rmg_mol return rmg_mol
def pybel_to_rmg(pybelmol, addh=False): """ignore charge, multiplicity, and bond orders""" mol = molecule.Molecule() if addh: pybelmol.addh() for pybelatom in pybelmol: num = pybelatom.atomicnum element = elements.getElement(num) atom = molecule.Atom(element=element, coords=np.array(pybelatom.coords)) mol.vertices.append(atom) for obbond in pybel.ob.OBMolBondIter(pybelmol.OBMol): begin_idx = obbond.GetBeginAtomIdx() - 1 end_idx = obbond.GetEndAtomIdx() - 1 bond = molecule.Bond(mol.vertices[begin_idx], mol.vertices[end_idx]) mol.addBond(bond) return mol.toSingleBonds()
def fromRDKitMol(mol, rdkitmol): """ Convert a RDKit Mol object `rdkitmol` to a molecular structure. Uses `RDKit <http://rdkit.org/>`_ to perform the conversion. This Kekulizes everything, removing all aromatic atom types. """ cython.declare(i=cython.int, radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int, number=cython.int, order=cython.float, atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond) mol.vertices = [] # Add hydrogen atoms to complete molecule if needed rdkitmol.UpdatePropertyCache(strict=False) rdkitmol = Chem.AddHs(rdkitmol) Chem.rdmolops.Kekulize(rdkitmol, clearAromaticFlags=True) # iterate through atoms in rdkitmol for i in xrange(rdkitmol.GetNumAtoms()): rdkitatom = rdkitmol.GetAtomWithIdx(i) # Use atomic number as key for element number = rdkitatom.GetAtomicNum() isotope = rdkitatom.GetIsotope() element = elements.getElement(number, isotope or -1) # Process charge charge = rdkitatom.GetFormalCharge() radicalElectrons = rdkitatom.GetNumRadicalElectrons() atom = mm.Atom(element, radicalElectrons, charge, '', 0) mol.vertices.append(atom) # Add bonds by iterating again through atoms for j in xrange(0, i): rdkitbond = rdkitmol.GetBondBetweenAtoms(i, j) if rdkitbond is not None: order = 0 # Process bond type rdbondtype = rdkitbond.GetBondType() if rdbondtype.name == 'SINGLE': order = 1 elif rdbondtype.name == 'DOUBLE': order = 2 elif rdbondtype.name == 'TRIPLE': order = 3 elif rdbondtype.name == 'QUADRUPLE': order = 4 elif rdbondtype.name == 'AROMATIC': order = 1.5 bond = mm.Bond(mol.vertices[i], mol.vertices[j], order) mol.addBond(bond) # We need to update lone pairs first because the charge was set by RDKit mol.updateLonePairs() # Set atom types and connectivity values mol.update() # Assume this is always true # There are cases where 2 radicalElectrons is a singlet, but # the triplet is often more stable, mol.multiplicity = mol.getRadicalCount() + 1 # mol.updateAtomTypes() return mol