def Alph33(obmol, f, a3, marker, n3): localmol = [] for i in range(n3): localmol.append(0) calc = 1 for obbond in ob.OBMolBondIter(obmol): #for obbond in ob.OBMolBondIter(obmol): #print(obbond.GetIdx()) for obbondin in ob.OBMolBondIter(obmol): if (obbondin.GetIdx() < calc): continue inend = (obbondin.GetEndAtom()).GetId() inbegin = (obbondin.GetBeginAtom()).GetId() end = (obbond.GetEndAtom()).GetId() begin = (obbond.GetBeginAtom()).GetId() if (begin == inbegin): first = obbond.GetEndAtom() mutual = obbond.GetBeginAtom() last = obbondin.GetEndAtom() # /list /mol /first -mutual- last check2(a3, obmol, first, mutual, last, n3, localmol) continue #2 if (begin == inend): first = obbond.GetEndAtom() mutual = obbond.GetBeginAtom() last = obbondin.GetBeginAtom() # /list /mol /first -mutual- last check2(a3, obmol, first, mutual, last, n3, localmol) continue #3 if (end == inbegin): first = obbond.GetBeginAtom() mutual = obbond.GetEndAtom() last = obbondin.GetEndAtom() # /list /mol /first -mutual- last check2(a3, obmol, first, mutual, last, n3, localmol) continue #4 if (end == inend): first = obbond.GetBeginAtom() mutual = obbond.GetEndAtom() last = obbondin.GetBeginAtom() # /list /mol /first -mutual- last check2(a3, obmol, first, mutual, last, n3, localmol) continue calc += 1 ##print(localmol) for i in range(n3): f.write(str(localmol[i]) + " ") f.write("\n")
def Alph3(obmol, f, a3, marker, n3): localmol = [] for i in range(n3): localmol.append(0) # n=0 calc = 1 for obbond in ob.OBMolBondIter(obmol): for obbondin in ob.OBMolBondIter(obmol): if (obbondin.GetIdx() < calc): continue inend = (obbondin.GetEndAtom()).GetId() inbegin = (obbondin.GetBeginAtom()).GetId() end = (obbond.GetEndAtom()).GetId() begin = (obbond.GetBeginAtom()).GetId() #found joint atom #1 if (begin == inbegin): first = obbond.GetEndAtom() mutual = obbond.GetBeginAtom() last = obbondin.GetEndAtom() # /list /mol /first -mutual- last n3 = check1(a3, obmol, first, mutual, last, n3, localmol) continue #2 if (begin == inend): first = obbond.GetEndAtom() mutual = obbond.GetBeginAtom() last = obbondin.GetBeginAtom() # /list /mol /first -mutual- last n3 = check1(a3, obmol, first, mutual, last, n3, localmol) continue #3 if (end == inbegin): first = obbond.GetBeginAtom() mutual = obbond.GetEndAtom() last = obbondin.GetEndAtom() # /list /mol /first -mutual- last n3 = check1(a3, obmol, first, mutual, last, n3, localmol) continue #4 if (end == inend): first = obbond.GetBeginAtom() mutual = obbond.GetEndAtom() last = obbondin.GetBeginAtom() # /list /mol /first -mutual- last n3 = check1(a3, obmol, first, mutual, last, n3, localmol) continue calc += 1 return n3
def to_graph(self, molw: pybel.Molecule) -> nx.Graph: mol = molw.OBMol if self._add_hydrogens: mol.AddHydrogens() else: mol.DeleteHydrogens() g = nx.Graph() for atom in openbabel.OBMolAtomIter(mol): node_features = { 'Symbol': self._element_tabel.GetSymbol(atom.GetAtomicNum()) } g.add_node(atom.GetIdx(), **node_features) self._node_types.add(node_features['Symbol']) for b in openbabel.OBMolBondIter(mol): idx_a = b.GetBeginAtomIdx() idx_b = b.GetEndAtomIdx() edge_features = {'BondType': b.GetBondOrder()} g.add_edge(idx_a, idx_b, **edge_features) self._edge_types.add(edge_features['BondType']) # canonical SMILES format text = molw.write(format='can') g.graph['smiles'] = text.split('\t', 1)[0] g.graph['name'] = molw.title.split('\t', 1)[0] return g
def mol2amol(mol): mol.Kekulize() atoms = list() for a in openbabel.OBMolAtomIter(mol): atom = list() atom.append(a.GetHyb()) atom.append(a.GetAtomicNum()) atom.append(a.GetFormalCharge()) atom.append(a.GetIsotope()) if a.IsClockwise(): stereo = 1 elif a.IsAntiClockwise(): stereo = 2 elif a.IsChiral(): stereo = 3 else: stereo = 0 atom.append(stereo) atom.append(a.GetSpinMultiplicity()) if a.IsAromatic(): aromatic = 1 else: aromatic = 0 atom.append(aromatic) atoms.append(atom) bonds = list() for b in openbabel.OBMolBondIter(mol): bond = list() bond.append(b.GetBeginAtomIdx()) bond.append(b.GetEndAtomIdx()) bond.append(b.GetBondOrder()) if b.IsWedge(): stereo = 1 elif b.IsHash(): stereo = 6 else: stereo = 0 bond.append(stereo) if b.IsAromatic(): aromatic = 1 else: aromatic = 0 bond.append(aromatic) if b.IsUp(): updown = 1 print updown elif b.IsDown(): updown = 2 print updown else: updown = 0 bond.append(updown) bonds.append(bond) return pickle.dumps([atoms, bonds], 2)
def _add_bondlength_change_collection(self, index, threshold=0, zorder=20, **kwargs): """Comute and draw bondlength changes on the axes.""" codes = [Path.MOVETO, Path.LINETO] col = [] amp = [] colors = [] for obbond in ob.OBMolBondIter(self.molecule): atom1, atom2 = (self.molecule.GetAtom(obbond.GetBeginAtomIdx()), self.molecule.GetAtom(obbond.GetEndAtomIdx())) atom1nc, atom2nc = [ self._to_normal_coordinates(atom, index) for atom in (atom1, atom2) ] if obbond.GetLength() == 0.0: logger.error( "Bond between %i and %i with length %.1f ignored." % (atom1.GetIdx(), atom2.GetIdx(), obbond.GetLength())) continue amplitude = atom1.GetDistance(atom2) - atom1nc.GetDistance(atom2nc) if abs(amplitude * 100) <= threshold: continue amp.append(abs(amplitude * 50)) colors.append(self.bond_colors[0 if amplitude < 0.0 else 1]) verts = (self._2Dcoords(atom1), self._2Dcoords(atom2)) segment = Path(verts, codes) col.append(segment) lw = 0.0 if not col else np.array(amp) * kwargs.pop("lw", 1.0) kw = {'edgecolors': colors, 'linewidths': lw} kwargs.update(kw) self._vib_bonds = PathCollection(col, zorder=zorder, **kwargs) self.axes.add_collection(self._vib_bonds)
def PybelModel_To_Fragmenter(mol): atoms = [] atomsXYZ = [] for i in mol.atoms: aname = i.type if aname[-1:] in '0123456789': aname = aname[:-1] if i.OBAtom.IsAromatic(): ar = 1 aname = aname.replace('ar', '') else: ar = 0 isotope = 0 ''' Place isotope treatment block here...... To be added..... ''' atoms.append( [i.OBAtom.GetExactMass(), aname, isotope, i.formalcharge, ar]) atomsXYZ.append([i.OBAtom.GetX(), i.OBAtom.GetY(), i.OBAtom.GetZ()]) bonds = [] for pb in openbabel.OBMolBondIter(mol.OBMol): if pb.IsAromatic(): bo = 4 else: bo = pb.GetBondOrder() i = pb.GetBeginAtomIdx() - 1 j = pb.GetEndAtomIdx() - 1 bonds.append([i, j, bo]) forces = [1.0] * len(atoms) ''' Place force estimations here if needed. ''' return [atoms, forces, bonds, atomsXYZ]
def calc_dist_min(mol, pos, ignore_bond=False): if not ignore_bond: bonds = ob.OBMolBondIter(mol) dist_list = [] for bond in bonds: begin_atom_idx = bond.GetBeginAtomIdx() - 1 # zero-indexed end_atom_idx = bond.GetEndAtomIdx() - 1 # zero-indexed #begin_atom, end_atom = bond.GetBeginAtom(), bond.GetEndAtom() #assert torch.all(pos[begin_atom_idx] == torch.tensor([begin_atom.x(), begin_atom.y(), begin_atom.z()], dtype=torch.float)).item() == True #assert torch.all(pos[end_atom_idx] == torch.tensor([end_atom.x(), end_atom.y(), end_atom.z()], dtype=torch.float)).item() == True dist = calc_dist(pos[begin_atom_idx], pos[end_atom_idx]) dist_list.append(dist.item()) if len(dist_list) > 0: return min(dist_list) else: return None else: dist_list = [] n = pos.size(0) for i in range(n - 1): for j in range(i + 1, n): assert i != j dist = calc_dist(pos[i], pos[j]) dist_list.append(dist) if len(dist_list) > 0: return min(dist_list) else: return None
def _construct_fragment_from_bonds(bonds): ''' takes as input a list of bonds of type OBBond and constructs a new openbabel molecule from those bonds and the atoms that constitute the start and end of those bonds. ''' fragment = ob.OBMol() added_atoms = [] for bond in bonds: atom_i = bond.GetBeginAtom() atom_j = bond.GetEndAtom() if atom_i not in added_atoms: fragment.AddAtom(atom_i) added_atoms.append(atom_i) atom_i_index = added_atoms.index(atom_i) if atom_j not in added_atoms: fragment.AddAtom(atom_j) added_atoms.append(atom_j) atom_j_index = added_atoms.index(atom_j) fragment.AddBond(atom_i_index + 1, atom_j_index + 1, bond.GetBondOrder()) for i, fragment_bond in enumerate(ob.OBMolBondIter(fragment)): mol_bond = bonds[i] if mol_bond.IsAromatic(): fragment_bond.SetAromatic() return (fragment)
def openbabel_count_bond_order(mol, bo=2): # pylint:disable=invalid-name """Count how often bond order bo occures in openbabel molecule mol""" count = 0 mole = mol.OBMol for bond in ob.OBMolBondIter(mole): if bond.GetBO() == bo: count += 1 return count
def rebuild_bonds(poltype,newmol, refmol): for b in openbabel.OBMolBondIter(refmol): beg = b.GetBeginAtomIdx() end = b.GetEndAtomIdx() if not newmol.GetBond(beg,end): newmol.AddBond(beg,end, b.GetBO(), b.GetFlags()) return newmol
def fromOBMol(mol, obmol): """ 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(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int) # cython.declare(atom=Atom, atom1=Atom, atom2=Atom, bond=Bond) 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): idx = obatom.GetIdx() #openbabel idx starts at 1! # Use atomic number as key for element number = obatom.GetAtomicNum() element = elements.getElement(number) # Process charge charge = obatom.GetFormalCharge() obatom_multiplicity = obatom.GetSpinMultiplicity() radicalElectrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0 atom = Atom(element, radicalElectrons, charge, '', 0) mol.vertices.append(atom) # iterate through bonds in obmol for obbond in openbabel.OBMolBondIter(obmol): order = 0 # Process bond type oborder = obbond.GetBondOrder() if oborder == 1: order = 'S' elif oborder == 2: order = 'D' elif oborder == 3: order = 'T' elif obbond.IsAromatic(): order = 'B' bond = Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1], mol.vertices[obbond.GetEndAtomIdx() - 1], order) #python array indices start at 0 mol.addBond(bond) # Set atom types and connectivity values mol.updateConnectivityValues() mol.updateAtomTypes() mol.updateMultiplicity() mol.updateLonePairs() # 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 return mol
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 cleanBonds(self): obiter = openbabel.OBMolBondIter(self.OBMol) n = self.natoms bonds_to_del = [] for bond in obiter: these_inds = [bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()] bonds_to_del.append(bond) for i in bonds_to_del: self.OBMol.DeleteBond(i)
def count_aromatic_bonds(mol): aromatic_bond_count = 0 total_bond_count = 0 for bond in ob.OBMolBondIter(mol): total_bond_count += 1 if bond.IsAromatic(): aromatic_bond_count += 1 print('%d bonds are aromatic (out of %d total)' % (aromatic_bond_count, total_bond_count))
def testIterators(self): """Basic check that at least two iterators are working""" mol = pybel.readstring("smi", "c1ccccc1C(=O)Cl") atoms = list(ob.OBMolAtomIter(mol.OBMol)) self.assertEqual(len(atoms), 9) elements = [atom.GetAtomicNum() for atom in atoms] self.assertEqual(elements, [6, 6, 6, 6, 6, 6, 6, 8, 17]) bonds = list(ob.OBMolBondIter(mol.OBMol)) self.assertEqual(len(bonds), 9)
def GenerateBondTopology(poltype,optmol): bondtopology=[] iterbond=openbabel.OBMolBondIter(optmol) # iterator for all bond objects in the molecule for bond in iterbond: a = bond.GetBeginAtom() b = bond.GetEndAtom() aidx=a.GetIdx() bidx=b.GetIdx() bondtopology.append(set([aidx,bidx])) return bondtopology
def populateBOMatrix(self): obiter = openbabel.OBMolBondIter(self.OBMol) n = self.natoms molBOMat = np.zeros((n, n)) for bond in obiter: these_inds = [bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()] this_order = bond.GetBondOrder() molBOMat[these_inds[0] - 1, these_inds[1] - 1] = this_order molBOMat[these_inds[1] - 1, these_inds[0] - 1] = this_order return (molBOMat)
def openbabel_count_bond_order(mol, bo=2): count = 0 mole = mol.OBMol for bond in ob.OBMolBondIter(mole): # Note: the OB implementation is wrong. It assumes that if all # atoms in the ring are aromatic then the ring itself must be # aromatic. This is not necessarily true. if bond.GetBO() == bo: count += 1 return count
def obabel_to_networkx3d(input_mol, **kwargs): # similarity_fn, atom_types=None, k=3, threshold=0): """ Takes a pybel molecule object and converts it into a networkx graph. :param input_mol: A molecule object :type input_mol: pybel.Molecule :param atom_types: A list containing the atomic number of atom types to be looked for in the molecule :type atom_types: list or None :param k: The number of nearest neighbors to be considered :type k: int :param label_name: the name to be used for the neighbors attribute :type label_name: string """ graph = nx.Graph() graph.graph['info'] = str(input_mol).strip() method = kwargs.get('method', 'metric') # Calculate pairwise distances between all atoms: coords = [] for atom in input_mol: coords.append(atom.coords) coords = np.asarray(coords) distances = scipy.spatial.distance.squareform( scipy.spatial.distance.pdist(coords)) # Find the nearest neighbors for each atom for atom in input_mol: atomic_no = str(atom.atomicnum) atom_type = str(atom.type) node_id = atom.idx - 1 graph.add_node(node_id) if method == "metric": graph.node[node_id]['label'] = find_nearest_neighbors( input_mol, distances, atom.idx, **kwargs) elif method == "topological": graph.node[node_id]['label'] = calculate_local_density( input_mol, distances, atom.idx, **kwargs) graph.node[node_id]['discrete_label'] = atomic_no graph.node[node_id]['atom_type'] = atom_type graph.node[node_id]['ID'] = node_id for bond in ob.OBMolBondIter(input_mol.OBMol): label = str(bond.GetBO()) graph.add_edge(bond.GetBeginAtomIdx() - 1, bond.GetEndAtomIdx() - 1, label=label) # print "current graph edges: " # print g.edges() return graph
def CreateNewClassVector(poltype,pmol,symmetry_classes, tmp_classes, frag_atoms, natoms): """ Intent: Find new symmetry classes if possible If two atoms were originally of the same sym class but are bound to atoms of differing sym classes, then these two atoms will now belong to two different sym classes Input: pmol: OBMol object symmetry_classes: previous set of symmetry classes tmp_classes: tmp array of new symmetry classes frag_atoms: atoms in largest fragment natoms: number of atoms Ouptut: tmp_classes is edited Referenced By: ExtendInvariants Description: 1. dict idx2index is created which maps atom idx's to an index ranging from 0 to # of symmetry classes - 1 2. For each atom a: a. For each bond b that a belongs to: i. Find the idx of the other atom, nbratom, in the bond b ii. Find and append the symmetry class that nbratom belongs to to vtmp b. Using vtmp, create a label for atom a i. This label contains information about the symmetry classes of the atoms that a is bound to ii. This label will be different for two atoms that were originally the same symmetry class but are bound to atoms of differing symmetry classes """ idx2index = dict() index = 0 del tmp_classes[:] for s in symmetry_classes: idx2index.update({s[0].GetIdx() : index}) index = index + 1 for s in symmetry_classes: iterbond = openbabel.OBMolBondIter(pmol) atom = s[0] idatom = s[1] nbridx = 0 vtmp = [] for b in iterbond: #if atom belongs to bond b if atom.GetIdx() == b.GetEndAtomIdx() or atom.GetIdx() == b.GetBeginAtomIdx(): if(atom.GetIdx() == b.GetEndAtomIdx()): nbridx = b.GetBeginAtomIdx() elif(atom.GetIdx() == b.GetBeginAtomIdx()): nbridx = b.GetEndAtomIdx() if(frag_atoms.BitIsOn(nbridx)): vtmp.append(symmetry_classes[idx2index[nbridx]][1]) vtmp.sort() m = 100 for v in vtmp: idatom = idatom + v * m m = 100 * m tmp_classes.append([atom,idatom])
def _make_bond_connectivity_from_openbabel(self, obmol): """Based upon the Open Babel/Pybel molecule, create a list of tuples to represent bonding information, where the three integers are the index of the starting atom, the index of the ending atom, and the bond order. """ bond_connectivities = [] for obbond in ob.OBMolBondIter(obmol): bond_connectivities.append( (obbond.GetBeginAtom().GetIndex(), obbond.GetEndAtom().GetIndex(), obbond.GetBondOrder())) return bond_connectivities
def genMolLinks(mol): links = [] for bond in ob.OBMolBondIter(mol.OBMol): bo = bond.GetBO() if bo != 1: for _ in range(bo): data = {'source':bond.GetBeginAtomIdx()-1,'target':bond.GetEndAtomIdx()-1} links.append(data) else: data = {'source':bond.GetBeginAtomIdx()-1,'target':bond.GetEndAtomIdx()-1} links.append(data) return links
def minimize(selection='tmp', forcefield='MMFF94', method='steepest descent', nsteps=2000, conv=1E-6, cutoff=False, cut_vdw=6.0, cut_elec=8.0, rigid_geometry=True): """ Use openbabel to minimize the energy of a molecule. """ pdb_string = cmd.get_pdbstr(selection) name = cmd.get_legal_name(selection) obconversion = ob.OBConversion() obconversion.SetInAndOutFormats('pdb', 'pdb') mol = ob.OBMol() obconversion.ReadString(mol, pdb_string) if rigid_geometry: constraints = ob.OBFFConstraints() for angle in ob.OBMolAngleIter(mol): b, a, c = [mol.GetAtom(x + 1) for x in angle] value = mol.GetAngle(a, b, c) b, a, c = [x + 1 for x in angle] constraints.AddAngleConstraint(a, b, c, value) for i in ob.OBMolBondIter(mol): a, b = (i.GetBeginAtomIdx(), i.GetEndAtomIdx()) value = i.GetLength() constraints.AddDistanceConstraint(a, b, value) ff = ob.OBForceField.FindForceField(forcefield) ff.Setup(mol, constraints) ff.SetConstraints(constraints) else: ff = ob.OBForceField.FindForceField(forcefield) ff.Setup(mol) if cutoff: ff.EnableCutOff(True) ff.SetVDWCutOff(cut_vdw) ff.SetElectrostaticCutOff(cut_elec) if method == 'conjugate gradients': ff.ConjugateGradients(nsteps, conv) else: ff.SteepestDescent(nsteps, conv) ff.GetCoordinates(mol) nrg = ff.Energy() pdb_string = obconversion.WriteString(mol) cmd.delete(name) if name == 'all': name = 'all_' cmd.delete(selection) cmd.read_pdbstr(pdb_string, selection) return nrg
def get_rotlist(traj, ligidx): ftype = 'xyz' ligidx_sort = sorted(ligidx) outp_xyz = write_xyz_from_md(traj, ligidx_sort) mymols = list([pybel.readstring(ftype, outp_xyz)]) mymol = mymols[0] iter_bond = openbabel.OBMolBondIter(mymol.OBMol) rotlist = [] for bond in iter_bond: if bond.IsRotor(): i1, i2 = (bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()) rotlist.append((ligidx_sort[i1 - 1], ligidx_sort[i2 - 1])) return rotlist
def remove_bond(self, idx1, idx2): """ Remove a bond from an openbabel molecule Args: idx1: The atom index of one of the atoms participating the in bond idx2: The atom index of the other atom participating in the bond """ for obbond in ob.OBMolBondIter(self._obmol): if (obbond.GetBeginAtomIdx() == idx1 and obbond.GetEndAtomIdx() == idx2) or (obbond.GetBeginAtomIdx() == idx2 and obbond.GetEndAtomIdx() == idx1): self._obmol.DeleteBond(obbond)
def mol_to_networkxgraph(mol): edges = [] bondorders = [] for bond in ob.OBMolBondIter(mol.OBMol): #bondorders.append(bond.GetBO()) if bond.GetBeginAtom().IsCarbon() and bond.GetEndAtom().IsCarbon(): edges.append( (bond.GetBeginAtomIdx() - 1, bond.GetEndAtomIdx() - 1, { 'BondOrder': bond.GetBO() })) g = nx.Graph() g.add_edges_from(edges) return g
def mol_to_data_v2(mol: openbabel.OBMol): """Extract data from OB Mol""" x = [] pos = [] for atom in openbabel.OBMolAtomIter(mol): x.append([ *[atom.GetAtomicNum() == i for i in [1, 6, 7, 8, 9]], # One hot atom type:H,C,N,O,F # atom.GetAtomicNum(), redundant atom.IsHbondAcceptor(), atom.IsHbondDonor(), atom.IsAromatic(), *[atom.GetHyb() == i for i in range(7)], # One hot hybridization *[atom.ExplicitHydrogenCount() == i for i in range(4)], # One hot hybridization atom.IsChiral(), *[atom.MemberOfRingSize() == i for i in [0, *range(3, 9)]], atom.IsAxial(), ]) pos.append([atom.GetX(), atom.GetY(), atom.GetZ()]) edge_index = [] edge_attr = [] for bond in openbabel.OBMolBondIter(mol): atom_a = bond.GetBeginAtomIdx() - 1 atom_b = bond.GetEndAtomIdx() - 1 edge_index.extend([ [atom_a, atom_b], [atom_b, atom_a], # both direction ]) edge_attr.extend([[ bond.IsInRing(), bond.IsSingle(), bond.IsDouble(), bond.IsTriple(), bond.IsAromatic(), bond.IsInRing(), bond.IsRotor(), bond.IsUp(), bond.IsDown(), bond.IsWedge(), bond.IsHash(), ]] * 2) edge_index = torch.tensor(np.array(edge_index).T, dtype=torch.long) edge_attr = torch.tensor(edge_attr, dtype=torch.float) y = None res = FP16_Data(x=torch.tensor(x, dtype=torch.float), edge_index=edge_index, edge_attr=edge_attr, y=y, pos=torch.tensor(pos, dtype=torch.float)) return res
def molecule_to_json(molecule): """Converts an OpenBabel molecule to json for use in Blender.""" # Save atom element type and 3D location. atoms = [{"element": atom.type, "location": atom.coords} for atom in molecule.atoms] # Save number of bonds and indices of endpoint atoms bonds = [{"atoms": [b.GetBeginAtom().GetIndex(), b.GetEndAtom().GetIndex()], "order": b.GetBondOrder()} for b in openbabel.OBMolBondIter(molecule.OBMol)] return json.dumps({"atoms": atoms, "bonds": bonds})
def obabel_to_networkx(mol): """ Takes a pybel molecule object and converts it into a networkx graph. """ g = nx.Graph() # atoms for atom in mol: label = str(atom.type) g.add_node(atom.idx, label=label) # bonds for bond in ob.OBMolBondIter(mol.OBMol): label = str(bond.GetBO()) g.add_edge(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), label=label) return g
def test_mol_iteration(self): mol = parse_smiles("c12c(O[CH](C1=O)C(C)C)cc1c(c2)ccc(=O)o1") element_counts = {} for atom in ob.OBMolAtomIter(mol): n = atom.GetAtomicNum() element_counts[n] = element_counts.get(n, 0) + 1 self.assertEqual(element_counts[8], 4) bond_counts = {} for bond in ob.OBMolBondIter(mol): n = bond.GetBondOrder() if not bond.IsAromatic(): bond_counts[n] = bond_counts.get(n, 0) + 1 self.assertEqual(bond_counts[2], 2)