def append_matrix_with_rmsd_to_previous_element( matrix, iterator, fieldname_rmsd="RMSD_to_previous"): import numpy ligands = [] foobar = None rmsd = 0 for pos in iterator: filename = matrix[pos]["filename"] ligands.append(openbabel.OBMol()) obconversion.SetInFormat(filename[filename.rfind(".") + 1:]) if obconversion.ReadFile(ligands[-1], filename): log.info('Successfully read ligand ' + str(filename)) else: log.warning('Failed to read ligand ' + str(filename)) if foobar == None: foobar = 1 # skip first continue else: #print "hi" foobar = openbabel.OBMolAtomIter(ligands[-2]) for atom in openbabel.OBMolAtomIter(ligands[-1]): V = foobar.__next__().GetVector() W = atom.GetVector() rmsd += (V.distSq(W)) rmsd /= ligands[-1].NumAtoms() rmsd = numpy.sqrt(rmsd) matrix[pos].update({fieldname_rmsd: rmsd}) return
def CheckBondConnectivity(poltype,mol,optmol): atomitermol=openbabel.OBMolAtomIter(mol) atomiteroptmol=openbabel.OBMolAtomIter(optmol) for atm in atomitermol: atmidxmol=atm.GetIdx() atmoptmol=optmol.GetAtom(atmidxmol) atmidxoptmol=atmoptmol.GetIdx() atmneighbidxlist=[] iteratomatommol = openbabel.OBAtomAtomIter(atm) for newatm in iteratomatommol: atmneighbidxlist.append(newatm.GetIdx()) atmneighbidxlistoptmol=[] iteratomatomoptmol = openbabel.OBAtomAtomIter(atmoptmol) for newatm in iteratomatomoptmol: atmneighbidxlistoptmol.append(newatm.GetIdx()) if set(atmneighbidxlist)!=set(atmneighbidxlistoptmol): if len(set(atmneighbidxlist))>len(set(atmneighbidxlistoptmol)): diff=set(atmneighbidxlist)-set(atmneighbidxlistoptmol) idxset='mol' else: diff=set(atmneighbidxlistoptmol)-set(atmneighbidxlist) idxset='optmol' RaiseConnectivityError(poltype,diff,idxset)
def ApplyKabsch(molFit, COMFit, COMRef, rot): crd=[] for at in openbabel.OBMolAtomIter(molFit): crd.append([at.GetX()-COMFit[0], at.GetY()-COMFit[1], at.GetZ()-COMFit[2]]) crd=np.array(crd) for i in xrange(len(crd)): crd[i]=np.dot(rot,crd[i]) i = 0 for at in openbabel.OBMolAtomIter(molFit): at.SetVector(crd[i][0]+COMRef[0], crd[i][1]+COMRef[1], crd[i][2]+COMRef[2]) i+=1 return True
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 get_atnums(self): if self._atnums is None: self._atnums = numpy.zeros((self.natoms, )) for at in openbabel.OBMolAtomIter(self.obmol): i = at.GetIdx() - 1 self._atnums[i] = at.GetAtomicNum() return self._atnums
def get_atmasses(self): if self._atmasses is None: self._atmasses = numpy.zeros((self.natoms, )) for at in openbabel.OBMolAtomIter(self.obmol): i = at.GetIdx() - 1 self._atmasses[i] = at.GetExactMass() return self._atmasses
def attype_groups_2(self): groupnames = ['NH', 'CO', 'CA', 'HA', 'CHB'] groups = [] for k in groupnames: groups.append([]) for at in openbabel.OBMolAtomIter(self.obmol): attype = at.GetResidue().GetAtomID(at) attype = attype.strip() if attype in ['1HB', '2HB', '3HB', 'HB1', 'HB2', 'HB3']: attype = 'HB' if attype in ['1H', '2H', 'H 1', 'H 2', 'H1', 'H2']: attype = 'HXT' if attype in ['N', 'H', 'HXT']: attype = 'NH' elif attype in ['C', 'O', 'OXT']: attype = 'CO' elif attype in ['CB', 'HB']: attype = 'CHB' ind = groupnames.index(attype) groups[ind].append(at.GetIdx() - 1) return groups, groupnames
def ComputeBondResidual(self, db): for f in self.frags: # constructing submolecule from the fragment efpmol = pyEFP.EFP2mol("./"+db.dirname+"/"+f.ename+"/"+f.fname+".efp") # fit atoms from the core lists rot, COMRef, COMFit = pyEFP.SolveKabsch(efpmol, f.subMol, f.efpcore, f.molcore) # deleting extra atoms complete = 0 while (complete == 0): complete = 1 for at in openbabel.OBMolAtomIter(efpmol): extra = 0 if at.GetIndex()+1 not in f.efptotal: extra = 1 for at1 in openbabel.OBAtomAtomIter(at): if (at1.GetIndex()+1 in f.efptotal) and (at.GetAtomicNum() == 1): extra = 0 break if (extra == 1): efpmol.DeleteAtom(at) complete = 0 efpmol.AddHydrogens() pyEFP.ApplyKabsch(efpmol, COMFit, COMRef, rot) for i in xrange(len(f.links)): dx = efpmol.GetAtom(f.links[i][0]).x() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).x() dy = efpmol.GetAtom(f.links[i][0]).y() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).y() dz = efpmol.GetAtom(f.links[i][0]).z() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).z() f.links[i].append(np.sqrt(dx*dx + dy*dy + dz*dz))
def get_connectivity(self): ''' Retrieve the connectivity matrix of the molecule. Returns: numpy.ndarray: (n_atoms x n_atoms) array containing the pairwise bond orders between atoms (0 for no bond). ''' if self._connectivity is None: # get connectivity matrix connectivity = np.zeros((self.n_atoms, len(self.numbers))) for atom in ob.OBMolAtomIter(self.get_obmol()): index = atom.GetIdx() - 1 # loop over all neighbors of atom for neighbor in ob.OBAtomAtomIter(atom): idx = neighbor.GetIdx() - 1 bond_order = neighbor.GetBond(atom).GetBO() #print(f'{index}-{idx}: {bond_order}') # do not count bonds between two hydrogen atoms if (self.numbers[index] == 1 and self.numbers[idx] == 1 and bond_order > 0): bond_order = 0 connectivity[index, idx] = bond_order self._connectivity = connectivity return self._connectivity
def enumerateChiral(mol): """ enumerate tetrahedral stereocenters in the molecule """ if not mol.IsChiral(): yield mol # we know the molecule is not chiral else: chiral = [] chiralSet = [] facade = ob.OBStereoFacade(mol) for a in ob.OBMolAtomIter(mol): idx = a.GetIdx() if a.IsChiral(): chiral.append(idx) if len(chiral) == 0: yield mol # no chiral centers else: atomList = chiral step = len(atomList) for winding in itertools.product([1,2], repeat=step): for idx, aIdx in enumerate(atomList): ts = facade.GetTetrahedralStereo(aIdx-1) config = ts.GetConfig() config.winding = winding[idx] config.specified = True ts.SetConfig(config) yield mol
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 make_conv_input(mol,A,B,gshape=64): """ Takes an openbabel molecule input, mol, and the atom indices for the two atoms for which you are interested in the coupling returns a flattend numpy array of the electrostatic potential with the X,Y,Z coordinates of A and B appended """ epsilon=0.00000001 grid=np.linspace(-6.,6.,gshape) XXX,YYY,ZZZ=np.meshgrid(grid,grid,grid) V=np.zeros((gshape,gshape,gshape,2)) atom_iter=ob.OBMolAtomIter(mol) for atom in atom_iter: atomic_num=atom.GetAtomicNum() x=atom.GetX() y=atom.GetY() z=atom.GetZ() RRR=np.sqrt((XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2) # V[:,:,:,0]=V[:,:,:,0] - atomic_num/(RRR+epsilon) V[:,:,:,0]=V[:,:,:,0]-atomic_num*np.exp(-0.5*RRR*RRR) atom=mol.GetAtom(A) x=atom.GetX() y=atom.GetY() z=atom.GetZ() RRR2=(XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2 V[:,:,:,1]=V[:,:,:,1] +np.exp(-0.5*(RRR2)) atom=mol.GetAtom(B) x=atom.GetX() y=atom.GetY() z=atom.GetZ() RRR2=(XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2 V[:,:,:,1]=V[:,:,:,1] +np.exp(-0.5*(RRR2)) return V
def getRingAtomsMulti(molfilePath): for m in pybel.readfile("mol", molfilePath): #print m.OBMol.GetFormula() outString = "" rings = m.OBMol.GetSSSR() numR = 0 for r in rings: numR = numR + 1 outString += "Ring count " + str(numR) + "\n" for r in rings: outString += "Ring size " + str(r.Size()) + "\n" path = r._path for p in path: outString += str(p - 1) + "\n" outString += "Atom count " + str(m.OBMol.NumAtoms()) + "\n" outString += "Index HowManyRings RingSize Hybridization Hydro_count Aromaticity AntiClockwise_chiral" + "\n" i = 0 for a in openbabel.OBMolAtomIter(m.OBMol): outString += str(i) + " " + str(a.MemberOfRingCount()) + " " + str( a.MemberOfRingSize()) + " " + str(a.GetHyb()) + " " + str( a.ImplicitHydrogenCount()) + " " if a.IsAromatic(): outString += "1" + " " else: outString += "0" + " " if a.IsClockwise(): outString += "1" + "\n" else: outString += "0" + "\n" i = i + 1 return outString
def assign_atom_types(selection='all'): """ TODO document me! read http://openbabel.org/dev-api/classOpenBabel_1_1OBAtom.shtml#ae09ed28481ac044dab3f31c8605b44a9 for available functions provided by openbabel to extract atom properties. There is a GetType() function but I found that function very limited. """ atom_types = [] pdb_string = cmd.get_pdbstr(selection) mol = ob.OBMol() obconversion = ob.OBConversion() obconversion.SetInAndOutFormats('pdb', 'pdb') obconversion.ReadString(mol, pdb_string) rings = mol.GetSSSR() for at in ob.OBMolAtomIter(mol): ring_member = [ring.IsMember(at) for ring in rings] neighbors = [ neighbor.GetAtomicNum() for neighbor in ob.OBAtomAtomIter(at) ] atom_types.append( (at.GetIndex(), at.GetAtomicNum(), at.GetHvyValence(), any(ring_member), at.IsAromatic(), at.MemberOfRingCount(), (neighbors))) return atom_types
def CalculateSymmetry(poltype,pmol, frag_atoms, symmetry_classes): """ Intent: Uses and builds on openbabel's 'GetGIVector' method which, "Calculates a set of graph invariant indexes using the graph theoretical distance, number of connected heavy atoms, aromatic boolean, ring boolean, atomic number, and summation of bond orders connected to the atom", to find initial symmetry classes. Input: pmol: OBMol object frag_atoms: OBBitVec object containing information about the largest fragment in 'pmol' symmetry_classes: the symmetry_classes array which will be filled in Output: nclasses: # of classes symmetry_classes: array is filled in Referenced By: gen_canonicallabels Description: 1. vectorUnsignedInt object is created, 'vgi' 2. It is filled in with the call to GetGIVector 3. The 'symmetry_classes' array is initially filled in to match with 'vgi' 4. These initial invariant classes do not suit our needs perfectly, so the ExtendInvariants method is called to find the more refined classes that we need """ vgi = openbabel.vectorUnsignedInt() natoms = pmol.NumAtoms() nfragatoms = frag_atoms.CountBits() pmol.GetGIVector(vgi) iteratom = openbabel.OBMolAtomIter(pmol) for atom in iteratom: idx = atom.GetIdx() if(frag_atoms.BitIsOn(idx)): symmetry_classes.append([atom, vgi[idx-1]]) nclasses = ExtendInvariants(poltype,pmol, symmetry_classes,frag_atoms,nfragatoms,natoms) return nclasses
def check_charges( self, negcharges=False): # negcharges True means that they are allowed atoms = list(openbabel.OBMolAtomIter(self.obmol)) for atom in self.G.nodes: a = atom - 1 # G indices are OBMol indices+1 if self.mapping: # means OBMol was loaded from G at some point a = self.mapping[atom] - 1 # G indices are OBMol indices+1 if self.G.nodes[atom]['Charge'] > 0: # iterate thru charged atoms if atoms[a].ExplicitHydrogenCount( ): # check if OBMol bonded a hydrogen to the atom to compensate for false charge self.G.nodes[atom]['Charge'] = 0 # reset charge in self.G self.obmol.BeginModify( ) # need this to make changes to existing OBMol object atoms[a].SetFormalCharge( 0 ) # delete charge (yes this will cause problems for >+1, but best method I could come up with) self.obmol.EndModify( ) # need this to save changes to existing OBMol object else: # set charge to 0, check valences, re-adjust if atoms[a].ImplicitHydrogenCount() > 0: self.G.nodes[atom]['Charge'] = 0 self.obmol.BeginModify() atoms[a].SetFormalCharge(0) self.obmol.EndModify() if self.G.nodes[atom][ 'Charge'] < 0 and negcharges is False: # means we will remove this neg charge self.G.nodes[atom]['Charge'] = 0 # set to 0 self.remove_hydrogens() # remove hydrogens that aren't needed anymore self.update() # reset OBMol, SMILES, and pybelMol return
def process_types(poltype, mol): """ Intent: Set up scalelist array for scaling certain multipole values For alchol, the quadrupole on O and H should be mannually scaled by 0.6. This only applies to OH that connect to sp3 Carbon. Similarly for NH in amine (that connects to a sp3 C), scale the Q by 0.75 or 75%. See JCC 2011 32(5):967-77. """ scalelist = {} multipole_scale_dict = {} for atm in openbabel.OBMolAtomIter(mol): if symm.get_class_number(poltype, atm.GetIdx()) not in scalelist: scalelist[symm.get_class_number(poltype, atm.GetIdx())] = [] scalelist[symm.get_class_number(poltype, atm.GetIdx())].append(None) scalelist[symm.get_class_number(poltype, atm.GetIdx())].append(None) scalelist[symm.get_class_number(poltype, atm.GetIdx())].append(None) multipole_scale_dict = {} #multipole_scale_dict['[OH][CX4]'] = [2, 0.6] #multipole_scale_dict['[NH2][CX4]'] = [2, 0.75] for (sckey, scval) in multipole_scale_dict.items(): sp = openbabel.OBSmartsPattern() openbabel.OBSmartsPattern.Init(sp, sckey) match = sp.Match(mol) for ia in sp.GetUMapList(): scalelist[symm.get_class_number(poltype, ia[0])][scval[0]] = scval[1] return scalelist
def FitCoords(self, db): Fitmol = openbabel.OBMol() for f in self.frags: # constructing submolecule from the fragment efpmol = pyEFP.EFP2mol("./"+db.dirname+"/"+f.ename+"/"+f.fname+".efp") # fit atoms from the core lists sys.stdout.flush() rot, COMRef, COMFit = pyEFP.SolveKabsch(efpmol, f.subMol, f.efpcore, f.molcore) f.rotat = [rot, COMRef, COMFit] # deleting extra atoms complete = 0 while (complete == 0): complete = 1 for at in openbabel.OBMolAtomIter(efpmol): extra = 0 if at.GetIndex()+1 not in f.efpcore: extra = 1 for at1 in openbabel.OBAtomAtomIter(at): if (at1.GetIndex()+1 in f.efpcore) and (at.GetAtomicNum() == 1): extra = 0 break if (extra == 1): efpmol.DeleteAtom(at) complete = 0 pyEFP.ApplyKabsch(efpmol, COMFit, COMRef, rot) Fitmol += efpmol return Fitmol
def save_structfile(poltype,molstruct, structfname): """ Intent: Output the data in the OBMol structure to a file (such as *.xyz) Input: molstruct: OBMol structure structfname: output file name Output: file is output to structfname Referenced By: tor_opt_sp, compute_mm_tor_energy Description: - """ strctext = os.path.splitext(structfname)[1] tmpconv = openbabel.OBConversion() if strctext in '.xyz': tmpfh = open(structfname, "w") maxidx = max(poltype.symmetryclass) iteratom = openbabel.OBMolAtomIter(molstruct) etab = openbabel.OBElementTable() tmpfh.write('%6d %s\n' % (molstruct.NumAtoms(), molstruct.GetTitle())) for ia in iteratom: tmpfh.write( '%6d %2s %13.6f %11.6f %11.6f %5d' % (ia.GetIdx(), etab.GetSymbol(ia.GetAtomicNum()), ia.x(), ia.y(), ia.z(), poltype.prmstartidx + (maxidx - poltype.symmetryclass[ia.GetIdx() - 1]))) iteratomatom = openbabel.OBAtomAtomIter(ia) neighbors = [] for iaa in iteratomatom: neighbors.append(iaa.GetIdx()) neighbors = sorted(neighbors) for iaa in neighbors: tmpfh.write('%5d' % iaa) tmpfh.write('\n') else: inFormat = openbabel.OBConversion.FormatFromExt(structfname) tmpconv.SetOutFormat(inFormat) return tmpconv.WriteFile(molstruct, structfname)
def make_mol_paths(mol, minpath, maxpath, smarts_flag): alist = list() molpath = list() for a in openbabel.OBMolAtomIter(mol): if a.GetAtomicNum() < 2: continue # break path for * or H atom make_atom_paths(molpath, alist, a, a, 0, minpath, maxpath, smarts_flag) del alist[:] return molpath
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 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 minimization(self, options=[]): temp1 = tempfile.NamedTemporaryFile(suffix='.pdb') temp2 = tempfile.NamedTemporaryFile(suffix='.pdb') bufMol = ob.OBMol() obConversion = ob.OBConversion() obConversion.SetInAndOutFormats('pdb', 'pdb') obConversion.WriteFile(self.molecule, temp1.name) popenargs = ['obminimize'] + options + [temp1.name] subprocess.run(popenargs, stdout=temp2) obConversion.ReadFile(bufMol, temp2.name) temp1.close() temp2.close() # Update coordinates pairs = zip(ob.OBMolAtomIter(self.molecule), ob.OBMolAtomIter(bufMol)) for (ai, aj) in pairs: x, y, z = aj.x(), aj.y(), aj.z() ai.SetVector(x, y, z)
def get_coordinates(self): if self._coords is None: self._coords = numpy.zeros((self.natoms, 3)) for at in openbabel.OBMolAtomIter(self.obmol): i = at.GetIdx() - 1 self._coords[i, 0] = at.GetX() self._coords[i, 1] = at.GetY() self._coords[i, 2] = at.GetZ() return self._coords
def get_binder_atom(binder, smarts): log.debug("Counting atoms to find the binder atom...") i = 1 for atom in openbabel.OBMolAtomIter(binder): log.debug(i) i += 1 if atom.MatchesSMARTS(smarts): log.debug("found ya!") return atom
def skelCN_groups(self, res): groupnames = [ 'NCA0', 'HA0', 'CO0', 'H+1', 'NCA+1', 'HA+1', 'CHB+1', 'CO+1', 'H+2', 'NCA+2', 'R' ] groups = [] for k in groupnames: groups.append([]) for at in openbabel.OBMolAtomIter(self.obmol): attype = at.GetResidue().GetAtomID(at) attype = attype.strip() rnum = at.GetResidue().GetNum() if attype in ['1HB', '2HB', '3HB', 'HB1', 'HB2', 'HB3']: attype = 'HB' if rnum == res: if attype in ['C', 'O']: attype = 'CO0' elif attype in ['N', 'CA']: attype = 'NCA0' elif attype in ['HA']: attype = 'HA0' else: attype = 'R' elif rnum == res + 1: if attype in ['H']: attype = 'H+1' elif attype in ['C', 'O']: attype = 'CO+1' elif attype in ['N', 'CA']: attype = 'NCA+1' elif attype in ['HA']: attype = 'HA+1' elif attype in ['CB', 'HB']: attype = 'CHB+1' elif rnum == res + 2: if attype in ['H']: attype = 'H+2' elif attype in ['N', 'CA']: attype = 'NCA+2' else: attype = 'R' else: attype = 'R' try: ind = groupnames.index(attype) except ValueError: print attype raise groups[ind].append(at.GetIdx() - 1) return groups, groupnames
def _compute_all_sybyl(system_ob, indices=None): sybyl_dict = {} for atom in ob.OBMolAtomIter(system_ob): if indices is not None and atom.GetIndex() not in indices: continue sybyl_dict[atom.GetIndex()] = atom.GetType() return (sybyl_dict)
def chain_ffopt(ff, mol, frozenats): ### FORCE FIELD OPTIMIZATION ## # INPUT # - ff: force field to use, available MMFF94, UFF< Ghemical, GAFF # - mol: mol3D to be ff optimized # - connected: indices of connection atoms to metal # - constopt: flag for constrained optimization # OUTPUT # - mol: force field optimized mol3D metals = range(21, 31) + range(39, 49) + range(72, 81) ### check requested force field ffav = 'mmff94, uff, ghemical, gaff, mmff94s' # force fields if ff.lower() not in ffav: print 'Requested force field not available. Defaulting to MMFF94' ff = 'mmff94' ### convert mol3D to OBMol via xyz file, because AFTER/END option have coordinates backup_mol = mol3D() backup_mol.copymol3D(mol) # print('bck ' + str(backup_mol.getAtom(0).coords())) # print('mol_ibf ' + str(mol.getAtom(0).coords())) mol.convert2OBMol() ### initialize constraints constr = openbabel.OBFFConstraints() ### openbabel indexing starts at 1 ### !!! # convert metals to carbons for FF indmtls = [] mtlsnums = [] for iiat, atom in enumerate(openbabel.OBMolAtomIter(OBMol)): if atom.atomicnum in metals: indmtls.append(iiat) mtlsnums.append(atom.GetAtomicNum()) atom.OBAtom.SetAtomicNum(19) for cat in frozenats: constr.AddAtomConstraint(cat + 1) # indexing babel ### set up forcefield forcefield = openbabel.OBForceField.FindForceField(ff) OBMol = mol.OBMol forcefield.Setup(obmol, constr) ## force field optimize structure forcefield.ConjugateGradients(2500) forcefield.GetCoordinates(OBMol) mol.OBMol = OBMol # reset atomic number to metal for i, iiat in enumerate(indmtls): mol.OBMol.GetAtomById(iiat).SetAtomicNum(mtlsnums[i]) mol.convert2mol3D() en = forcefield.Energy() # print(str(mol.OBmol.atoms[1].OBAtom.GetVector().GetZ())) # print(str(forcefield.Validate())) # print('mol_af ' + str(mol.getAtom(0).coords())) # print('ff delta = ' + str(backup_mol.rmsd(mol))) del forcefield, constr, OBMol return mol, en
def pymatgen_mol(self): """ Returns pymatgen Molecule object. """ sp = [] coords = [] for atom in ob.OBMolAtomIter(self._obmol): sp.append(atom.GetAtomicNum()) coords.append([atom.GetX(), atom.GetY(), atom.GetZ()]) return Molecule(sp, coords)