def test_findCycles3(): # test cycle detection on taxol merged rings only atoms, bonds = getGraphFromFile('Data/fuzedRings1.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount==4
def test_findCycles1(): # test cycle detection on taxol atoms, bonds = getGraphFromFile('Data/txp.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount == 6
def test_findCycles1(): # test cycle detection on taxol atoms, bonds = getGraphFromFile('Data/txp.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount==6
def test_findCycles2(): # test cycle detection on modified taxol to have 5 membered ring atoms, bonds = getGraphFromFile('Data/fuzedRings2.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount==4
def test_findCycles4(): # test that atoms in cycles are ordered on taxol atoms, bonds = getGraphFromFile('Data/txp.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) def hasBond(a1, a2, cycleHasBond): for b in cyclebonds: if b.atom1==a1 and b.atom2==a2: return 1 elif b.atom1==a2 and b.atom2==a1: return 1 return 0 def isOrdered(cycleatoms, cyclebonds): def hasBond(a1, a2, cyclebonds): for b in cyclebonds: if b.atom1==a1 and b.atom2==a2: return 1 elif b.atom1==a2 and b.atom2==a1: return 1 return 0 start = cycleatoms[0] for end in cycleatoms[1:]: if not hasBond(start, end, cyclebonds): return 0 start = end return 1 for r in rings.rings: assert isOrdered(r['atoms'], r['bonds'])
def test_findCycles3(): # test cycle detection on taxol merged rings only atoms, bonds = getGraphFromFile('Data/fuzedRings1.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount == 4
def test_findCycles2(): # test cycle detection on modified taxol to have 5 membered ring atoms, bonds = getGraphFromFile('Data/fuzedRings2.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) assert rings.ringCount == 4
def test_findCycles4(): # test that atoms in cycles are ordered on taxol atoms, bonds = getGraphFromFile('Data/txp.graph') from PyBabel.cycle import RingFinder rings = RingFinder() rings.findRings2(atoms, bonds) def hasBond(a1, a2, cycleHasBond): for b in cyclebonds: if b.atom1 == a1 and b.atom2 == a2: return 1 elif b.atom1 == a2 and b.atom2 == a1: return 1 return 0 def isOrdered(cycleatoms, cyclebonds): def hasBond(a1, a2, cyclebonds): for b in cyclebonds: if b.atom1 == a1 and b.atom2 == a2: return 1 elif b.atom1 == a2 and b.atom2 == a1: return 1 return 0 start = cycleatoms[0] for end in cycleatoms[1:]: if not hasBond(start, end, cyclebonds): return 0 start = end return 1 for r in rings.rings: assert isOrdered(r['atoms'], r['bonds'])
def select(self, bnds, bondOrder=1): ats = self.getAtoms(bnds) mols = ats.top.uniq() atype = AtomHybridization() for m in mols: if not m.chains[0].hasBonds: m.buildBondsByDistance() allAts = m.chains.residues.atoms atype.assignHybridization(allAts) rf = RingFinder() rf.findRings2(allAts, allAts.bonds[0]) bo = BondOrder() bo.assignBondOrder(allAts, allAts.bonds[0], rf) return BondSet(bnds.get(lambda x, ord=bondOrder: x.bondOrder==ord))
def select(self, bnds, bondOrder=1): ats = self.getAtoms(bnds) mols = ats.top.uniq() atype = AtomHybridization() for m in mols: if not m.chains[0].hasBonds: m.buildBondsByDistance() allAts = m.chains.residues.atoms atype.assignHybridization(allAts) rf = RingFinder() rf.findRings2(allAts, allAts.bonds[0]) bo = BondOrder() bo.assignBondOrder(allAts, allAts.bonds[0], rf) return BondSet(bnds.get(lambda x, ord=bondOrder: x.bondOrder == ord))
def getLigandBondDict(self): ats = self.allAtoms babel = AtomHybridization() babel.assignHybridization(self.allAtoms) #typeBonds??? #typeAtoms(ats) rf = RingFinder() rf.findRings2(ats, ats.bonds[0]) ct = 1 bondDict = {} for ring in rf.rings: bondDict[ct] = ring['bonds'] for b in ring['bonds']: b.cyclenum = ct ct = ct + 1 self.cyclecount = rf.ringCount self.bondDict = bondDict
def getLigandBondDict(self): ats = self.allAtoms babel = AtomHybridization() babel.assignHybridization(self.allAtoms) #typeBonds??? #typeAtoms(ats) rf = RingFinder() rf.findRings2(ats, ats.bonds[0]) ct = 1 bondDict = {} for ring in rf.rings: bondDict[ct] = ring['bonds'] for b in ring['bonds']: b.cyclenum = ct ct = ct + 1 self.cyclecount = rf.ringCount self.bondDict = bondDict
def select(self, bnds): ats = self.getAtoms(bnds) rf = RingFinder() #nb maxSize of ring is 20 by default rf.findRings2(ats, bnds, maxSize=len(ats)) ats = self.getAtoms(rf.allRingBonds) allAts = ats.top.uniq().allAtoms atype = AtomHybridization() atype.assignHybridization(allAts) bo = BondOrder() bo.assignBondOrder(allAts, allAts.bonds[0], rf) arom = Aromatic(rf) arom.find_aromatic_atoms(ats) aromatic_bnds = ats.bonds[0].get(lambda x: x.bondOrder == 'aromatic') aromatic_ats = self.getAtoms(aromatic_bnds) aromatic_ats.aromatic = 1 return aromatic_bnds
def select(self, bnds): ats = self.getAtoms(bnds) rf = RingFinder() #nb maxSize of ring is 20 by default rf.findRings2(ats, bnds, maxSize=len(ats)) ats = self.getAtoms(rf.allRingBonds) allAts = ats.top.uniq().allAtoms atype = AtomHybridization() atype.assignHybridization(allAts) bo = BondOrder() bo.assignBondOrder(allAts, allAts.bonds[0], rf) arom = Aromatic(rf) arom.find_aromatic_atoms(ats) aromatic_bnds = ats.bonds[0].get(lambda x: x.bondOrder=='aromatic') aromatic_ats = self.getAtoms(aromatic_bnds) aromatic_ats.aromatic = 1 return aromatic_bnds
def select(self, bnds, detectAll=False): ats = self.getAtoms(bnds) rf = RingFinder() if self.useMaxSize: # increase maxSize of ring rf.findRings2(ats, bnds, maxSize=len(ats)) else: #limit maxSize of ring to default 20 rf.findRings2(ats, bnds) #check for connected cycles bonds = BondSet(rf.allRingBonds) if detectAll and len(rf.allRingBonds): ats = BondSet(rf.allRingBonds).getAtoms() ANS = {} for a in ats: for b in a.bonds: if b.atom1 in ats and b.atom2 in ats: ANS[b] = 1 #return BondSet(rf.allRingBonds) bonds = BondSet(ANS.keys()) return bonds
def select(self, bnds, detectAll=False): ats = self.getAtoms(bnds) rf = RingFinder() if self.useMaxSize: # increase maxSize of ring rf.findRings2(ats, bnds, maxSize=len(ats)) else: #limit maxSize of ring to default 20 rf.findRings2(ats, bnds) #check for connected cycles bonds= BondSet(rf.allRingBonds) if detectAll and len(rf.allRingBonds): ats = BondSet(rf.allRingBonds).getAtoms() ANS = {} for a in ats: for b in a.bonds: if b.atom1 in ats and b.atom2 in ats: ANS[b] = 1 #return BondSet(rf.allRingBonds) bonds= BondSet(ANS.keys()) return bonds
def select(self, bnds, cutoff=7.5): cutoffValue = math.cos(cutoff*math.pi/180.) #print "cutoffValue=", cutoffValue aromaticCs = AtomSet([]) atD = {} ctr = 1 aromaticBnds = BondSet() #taken from autotorsCommands ats = self.getAtoms(bnds) rf = RingFinder() rf.findRings2(ats, bnds) cyclecount = rf.ringCount aromatic_cycles = [] ct = 1 for ring in rf.rings: blist = ring['bonds'] for bnd in blist: at = bnd.atom1 #next find the other bond in this cycle with at as one of the atoms: z2 = filter(lambda x:x!=bnd and x.atom1==at or x.atom2==at, blist) bnd.nextbond = z2[0] neighbor = z2[0].atom1 if neighbor==at: neighbor = z2[0].atom2 bnd.next1 = neighbor #print "set ", bnd.atom1.name,'-', bnd.atom2.name,".next1 to ", neighbor.name #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 at1 = bnd.next1 at2 = bnd.atom1 at3 = bnd.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a1 = Numeric.subtract(pt2,pt1) b1 = Numeric.subtract(pt3,pt2) p = [a1[1]*b1[2]-a1[2]*b1[1],a1[2]*b1[0]-a1[0]*b1[2],a1[0]*b1[1]-a1[1]*b1[0]] result0 = Numeric.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]) bnd.nrmsize = result0 result1 = p bnd.nrms = result1 #next find the other bond w/atom2: z2 = filter(lambda x,bnd=bnd, at2=bnd.atom2, blist=blist:x!=bnd and x.atom1==at2 or x.atom2==at2, blist) #finally, return the other atom in this bond bnd.nextbond2 = z2[0] if bnd.nextbond2==bnd: bnd.nextbond2 = z2[1] #neighbor2 = self._getnxtAtom(b.atom2,b.nextbond2) neighbor2 = bnd.nextbond2.atom1 if neighbor2==bnd.atom2: neighbor2 = bnd.nextbond2.atom2 bnd.next2 = neighbor2 #next have to check whether the normals are parallel #check each pair in each bond, how to keep track?? #have to get normal at b's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for bnd in blist: p = bnd.nrms psize = bnd.nrmsize q = bnd.nextbond2.nrms qsize = bnd.nextbond2.nrmsize #theta is the critical test for planarity: #if angle between 2 nrms is 0, atoms are planar #NB>test is comparing theta,cos(angle), w/zero bnd.theta = Numeric.dot(p,q)/(psize*qsize) #NB: REPEAT STUFF FROM HERE TO THE END IF aromaticCutOff changes ct = 0 for bnd in blist: #these are values for the default 7.5degrees: #if theta>=0.997 or theta<=-0.997: #print bnd.atom1.name, '-', bnd.atom2.name, '->', bnd.theta if bnd.theta>=cutoffValue or bnd.theta<=-cutoffValue: bnd.posAromatic = 1 ct = ct + 1 else: bnd.posAromatic = 0 #print ' posAromatic=', bnd.posAromatic #after checking all the bonds in current cycle, compare #posAromatic w/number if ct==len(blist): #print ctr," cycle is aromatic" #NB: only C=C bonds are considered aromatic # could change the name and autodock_element here.... for bnd in blist: # THIS IS WRONG!!! #if bnd.atom1.element=='C' and bnd.atom2.element=='C': # aromaticBnds.append(bnd) aromaticBnds.append(bnd) ctr = ctr + 1 #print "len(aromaticBnds)=", len(aromaticBnds) #for b in aromaticBnds: # print b.atom1.name, '-', b.atom2.name return aromaticBnds
def detectPiInteractions(self, tolerance=0.95, debug=False, use_all_cycles=False): if debug: print("in detectPiInteractions") self.results['pi_pi'] = [] #stacked rings...? self.results['t_shaped'] = [] #one ring perpendicular to the other self.results['cation_pi'] = [] # self.results['pi_cation'] = [] # self.results['macro_cations'] = []# self.results['lig_cations'] = [] # #at this point have self.results if not len(self.results['lig_close_atoms']): return lig_atoms = self.results['lig_close_atoms'].parent.uniq().atoms macro_res = self.results['macro_close_atoms'].parent.uniq() if not len(macro_res): return macro_atoms = macro_res.atoms l_rf = RingFinder() #Ligand l_rf.findRings2(lig_atoms, lig_atoms.bonds[0]) #rf.rings is list of dictionaries, one per ring, with keys 'bonds' and 'atoms' if debug: print("LIG: len(l_rf.rings)=", len(l_rf.rings)) if not len(l_rf.rings): if debug: print("no lig rings found by l_rf!") return acbs = self.aromatic_cycle_bond_selector #acbs = AromaticCycleBondSelector() lig_rings = [] for r in l_rf.rings: ring_bnds = r['bonds'] if use_all_cycles: lig_rings.append(ring_bnds) else: arom_bnds = acbs.select(ring_bnds) if len(arom_bnds)>4: lig_rings.append(arom_bnds) if debug: print("LIG: len(lig_arom_rings)=", len(lig_rings)) self.results['lig_rings'] = lig_rings self.results['lig_ring_atoms'] = AtomSet() #only check for pi-cation if lig_rings exist if len(lig_rings): macro_cations = self.results['macro_cations'] = self.getCations(macro_atoms) macro_cations = macro_cations.get(lambda x: x.element!='H') lig_ring_atoms = AtomSet() u = {} for r in lig_rings: for a in BondSet(r).getAtoms(): u[a] = 1 if len(u): lig_ring_atoms = AtomSet(list(u.keys())) lig_ring_atoms.sort() self.results['lig_ring_atoms'] = lig_ring_atoms if len(macro_cations): if debug: print("check distances from lig_rings to macro_cations here") #macro cations->lig rings pairDict2 = self.distanceSelector.select(lig_ring_atoms,macro_cations) z = {} for key,v in list(pairDict2.items()): val = v.tolist()[0] if val in macro_cations: z[val] = [key] if len(z): self.results['pi_cation'] = (list(z.items())) else: self.results['pi_cation'] = [] #check the distance between the rings and the macro_cations self.results['lig_cations'] = self.getCations(lig_atoms) lig_cations = self.results['lig_cations'] #remove hydrogens lig_cations = lig_cations.get(lambda x: x.element!='H') #Macromolecule m_rf = RingFinder() m_rf.findRings2(macro_res.atoms, macro_res.atoms.bonds[0]) #rf.rings is list of dictionaries, one per ring, with keys 'bonds' and 'atoms' if debug: print("MACRO: len(m_rf.rings)=", len(m_rf.rings)) if not len(m_rf.rings): if debug: print("no macro rings found by m_rf!") return macro_rings = [] for r in m_rf.rings: ring_bnds = r['bonds'] if use_all_cycles: macro_rings.append(ring_bnds) else: arom_bnds = acbs.select(ring_bnds) if len(arom_bnds)>4: macro_rings.append(arom_bnds) if debug: print("len(macro_arom_rings)=", len(macro_rings)) self.results['macro_rings'] = macro_rings self.results['macro_ring_atoms'] = AtomSet() #only check for pi-cation if macro_rings exist if len(macro_rings): macro_ring_atoms = AtomSet() u = {} for r in macro_rings: for a in BondSet(r).getAtoms(): #new method of bondSets u[a] = 1 if len(u): macro_ring_atoms = AtomSet(list(u.keys())) macro_ring_atoms.sort() self.results['macro_ring_atoms'] = macro_ring_atoms if len(lig_cations): if debug: print("check distances from macro_rings to lig_cations here") pairDict3 = self.distanceSelector.select(macro_ring_atoms,lig_cations) z = {} for x in list(pairDict3.items()): #lig cations->macro rings z.setdefault(x[1].tolist()[0], []).append(x[0]) if len(z): self.results['cation_pi'] = (list(z.items())) else: self.results['cation_pi'] = [] #macro_pi_atoms = AtomSet(pairDict3.keys()) #l_cations = AtomSet() #for v in pairDict3.values(): # for x in v: # l_cations.append(x) #self.results['cation_pi'] = pairDict3.items() #self.results['cation_pi'] = (l_cations, macro_pi_atoms) #check for intermol distance <6 Angstrom (J.ComputChem 29:275-279, 2009) #compare each lig_ring vs each macro_ring for lig_ring_bnds in lig_rings: lig_atoms = acbs.getAtoms(lig_ring_bnds) lig_atoms.sort() if debug: print("len(lig_atoms)=", len(lig_atoms)) #--------------------------------- # compute the normal to lig ring #--------------------------------- a1 = numpy.array(lig_atoms[0].coords) a2 = numpy.array(lig_atoms[2].coords) a3 = numpy.array(lig_atoms[4].coords) if debug: print("a1,a2, a3=", a1.tolist(), a2.tolist(), a3.tolist()) for macro_ring_bnds in macro_rings: macro_atoms = acbs.getAtoms(macro_ring_bnds) macro_atoms.sort() if debug: print("len(macro_atoms)=", len(macro_atoms)) pD_dist = self.distanceSelectorWithCutoff.select(macro_ring_atoms, lig_atoms, cutoff=self.dist_cutoff) if not len(pD_dist[0]): if debug: print("skipping ligand ring ", lig_rings.index(lig_ring_bnds), " vs ", end=' ') print("macro ring", macro_rings.index(macro_ring_bnds)) continue #--------------------------------- # compute the normal to macro ring #--------------------------------- b1 = numpy.array(macro_atoms[0].coords) b2 = numpy.array(macro_atoms[2].coords) b3 = numpy.array(macro_atoms[4].coords) if debug: print("b1,b2, b3=", b1.tolist(), b2.tolist(), b3.tolist()) # check for stacking a2_1 = a2-a1 a3_1 = a3-a1 b2_1 = b2-b1 b3_1 = b3-b1 if debug: print("a2_1 = ", a2-a1) if debug: print("a3_1 = ", a3-a1) if debug: print("b2_1 = ", b2-b1) if debug: print("b3_1 = ", b3-b1) n1 = crossProduct(a3_1,a2_1) #to get the normal for the first ring n2 = crossProduct(b3_1,b2_1) #to get the normal for the second ring if debug: print("n1=", n1) if debug: print("n2=", n2) n1 = numpy.array(n1) n2 = numpy.array(n2) n1_dot_n2 = numpy.dot(n1,n2) if debug: print("n1_dot_n2", numpy.dot(n1,n2)) if abs(n1_dot_n2) >= 1*tolerance: if debug: print("The rings are stacked vertically") new_result = (acbs.getAtoms(lig_ring_bnds), acbs.getAtoms(macro_ring_bnds)) self.results['pi_pi'].append(new_result) if abs(n1_dot_n2) <= 0.01*tolerance: if debug: print("The rings are stacked perpendicularly") new_result = (acbs.getAtoms(lig_ring_bnds), acbs.getAtoms(macro_ring_bnds)) self.results['t_shaped'].append(new_result)
def detectPiInteractions(self, tolerance=0.95, debug=False, use_all_cycles=False): if debug: print "in detectPiInteractions" self.results['pi_pi'] = [] #stacked rings...? self.results['t_shaped'] = [] #one ring perpendicular to the other self.results['cation_pi'] = [] # self.results['pi_cation'] = [] # self.results['macro_cations'] = []# self.results['lig_cations'] = [] # #at this point have self.results lig_res = self.results['lig_close_res'] if not len(lig_res): return lig_atoms = lig_res.atoms macro_res = self.results['macro_close_res'] if not len(macro_res): return macro_atoms = macro_res.atoms l_rf = RingFinder() #Ligand l_rf.findRings2(lig_res.atoms, lig_res.atoms.bonds[0]) #rf.rings is list of dictionaries, one per ring, with keys 'bonds' and 'atoms' if debug: print "LIG: len(l_rf.rings)=", len(l_rf.rings) if not len(l_rf.rings): if debug: print "no lig rings found by l_rf!" return acbs = AromaticCycleBondSelector() lig_rings = [] for r in l_rf.rings: ring_bnds = r['bonds'] if use_all_cycles: lig_rings.append(ring_bnds) else: arom_bnds = acbs.select(ring_bnds) if len(arom_bnds)>4: lig_rings.append(arom_bnds) if debug: print "LIG: len(lig_arom_rings)=", len(lig_rings) self.results['lig_rings'] = lig_rings self.results['lig_ring_atoms'] = AtomSet() #only check for pi-cation if lig_rings exist if len(lig_rings): macro_cations = self.results['macro_cations'] = self.getCations(macro_atoms) lig_ring_atoms = AtomSet() u = {} for r in lig_rings: for a in BondSet(r).getAtoms(): u[a] = 1 if len(u): lig_ring_atoms = AtomSet(u.keys()) lig_ring_atoms.sort() self.results['lig_ring_atoms'] = lig_ring_atoms if len(macro_cations): if debug: print "check distances from lig_rings to macro_cations here" #macro cations->lig rings pairDict2 = self.distanceSelector.select(lig_ring_atoms,macro_cations) z = {} for key,v in pairDict2.items(): val = v.tolist()[0] if val in macro_cations: z[val] = [key] if len(z): self.results['pi_cation'] = (z.items()) else: self.results['pi_cation'] = [] #check the distance between the rings and the macro_cations self.results['lig_cations'] = self.getCations(lig_atoms) #Macromolecule m_rf = RingFinder() m_rf.findRings2(macro_res.atoms, macro_res.atoms.bonds[0]) #rf.rings is list of dictionaries, one per ring, with keys 'bonds' and 'atoms' if debug: print "MACRO: len(m_rf.rings)=", len(m_rf.rings) if not len(m_rf.rings): if debug: print "no macro rings found by m_rf!" return macro_rings = [] for r in m_rf.rings: ring_bnds = r['bonds'] if use_all_cycles: macro_rings.append(ring_bnds) else: arom_bnds = acbs.select(ring_bnds) if len(arom_bnds)>4: macro_rings.append(arom_bnds) if debug: print "len(macro_arom_rings)=", len(macro_rings) self.results['macro_rings'] = macro_rings self.results['macro_ring_atoms'] = AtomSet() #only check for pi-cation if macro_rings exist if len(macro_rings): lig_cations = self.results['lig_cations'] = self.getCations(lig_atoms) macro_ring_atoms = AtomSet() u = {} for r in macro_rings: for a in BondSet(r).getAtoms(): #new method of bondSets u[a] = 1 if len(u): macro_ring_atoms = AtomSet(u.keys()) macro_ring_atoms.sort() self.results['macro_ring_atoms'] = macro_ring_atoms if len(lig_cations): if debug: print "check distances from macro_rings to lig_cations here" pairDict3 = self.distanceSelector.select(macro_ring_atoms,lig_cations) z = {} for x in pairDict3.items(): #lig cations->macro rings z.setdefault(x[1].tolist()[0], []).append(x[0]) if len(z): self.results['cation_pi'] = (z.items()) else: self.results['cation_pi'] = [] #macro_pi_atoms = AtomSet(pairDict3.keys()) #l_cations = AtomSet() #for v in pairDict3.values(): # for x in v: # l_cations.append(x) #self.results['cation_pi'] = pairDict3.items() #self.results['cation_pi'] = (l_cations, macro_pi_atoms) #check for intermol distance <6 Angstrom (J.ComputChem 29:275-279, 2009) #compare each lig_ring vs each macro_ring for lig_ring_bnds in lig_rings: lig_atoms = acbs.getAtoms(lig_ring_bnds) lig_atoms.sort() if debug: print "len(lig_atoms)=", len(lig_atoms) #--------------------------------- # compute the normal to lig ring #--------------------------------- a1 = Numeric.array(lig_atoms[0].coords) a2 = Numeric.array(lig_atoms[2].coords) a3 = Numeric.array(lig_atoms[4].coords) if debug: print "a1,a2, a3=", a1.tolist(), a2.tolist(), a3.tolist() for macro_ring_bnds in macro_rings: macro_atoms = acbs.getAtoms(macro_ring_bnds) macro_atoms.sort() if debug: print "len(macro_atoms)=", len(macro_atoms) pD_dist = self.distanceSelectorWithCutoff.select(macro_ring_atoms, lig_atoms, cutoff=self.dist_cutoff) if not len(pD_dist[0]): if debug: print "skipping ligand ring ", lig_rings.index(lig_ring_bnds), " vs ", print "macro ring", macro_rings.index(macro_ring_bnds) continue #--------------------------------- # compute the normal to macro ring #--------------------------------- b1 = Numeric.array(macro_atoms[0].coords) b2 = Numeric.array(macro_atoms[2].coords) b3 = Numeric.array(macro_atoms[4].coords) if debug: print "b1,b2, b3=", b1.tolist(), b2.tolist(), b3.tolist() # check for stacking a2_1 = a2-a1 a3_1 = a3-a1 b2_1 = b2-b1 b3_1 = b3-b1 if debug: print "a2_1 = ", a2-a1 if debug: print "a3_1 = ", a3-a1 if debug: print "b2_1 = ", b2-b1 if debug: print "b3_1 = ", b3-b1 n1 = crossProduct(a3_1,a2_1) #to get the normal for the first ring n2 = crossProduct(b3_1,b2_1) #to get the normal for the second ring if debug: print "n1=", n1 if debug: print "n2=", n2 n1 = Numeric.array(n1) n2 = Numeric.array(n2) n1_dot_n2 = Numeric.dot(n1,n2) if debug: print "n1_dot_n2", Numeric.dot(n1,n2) if abs(n1_dot_n2) >= 1*tolerance: if debug: print "The rings are stacked vertically" new_result = (acbs.getAtoms(lig_ring_bnds), acbs.getAtoms(macro_ring_bnds)) self.results['pi_pi'].append(new_result) if abs(n1_dot_n2) <= 0.01*tolerance: if debug: print "The rings are stacked perpendicularly" new_result = (acbs.getAtoms(lig_ring_bnds), acbs.getAtoms(macro_ring_bnds)) self.results['t_shaped'].append(new_result)
def select(self, bnds, cutoff=7.5): cutoffValue = math.cos(cutoff * math.pi / 180.) #print "cutoffValue=", cutoffValue aromaticCs = AtomSet([]) atD = {} ctr = 1 aromaticBnds = BondSet() #taken from autotorsCommands ats = self.getAtoms(bnds) rf = RingFinder() rf.findRings2(ats, bnds) cyclecount = rf.ringCount aromatic_cycles = [] ct = 1 for ring in rf.rings: blist = ring['bonds'] for bnd in blist: at = bnd.atom1 #next find the other bond in this cycle with at as one of the atoms: z2 = filter( lambda x: x != bnd and x.atom1 == at or x.atom2 == at, blist) bnd.nextbond = z2[0] neighbor = z2[0].atom1 if neighbor == at: neighbor = z2[0].atom2 bnd.next1 = neighbor #print "set ", bnd.atom1.name,'-', bnd.atom2.name,".next1 to ", neighbor.name #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 at1 = bnd.next1 at2 = bnd.atom1 at3 = bnd.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a1 = Numeric.subtract(pt2, pt1) b1 = Numeric.subtract(pt3, pt2) p = [ a1[1] * b1[2] - a1[2] * b1[1], a1[2] * b1[0] - a1[0] * b1[2], a1[0] * b1[1] - a1[1] * b1[0] ] result0 = Numeric.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) bnd.nrmsize = result0 result1 = p bnd.nrms = result1 #next find the other bond w/atom2: z2 = filter(lambda x, bnd=bnd, at2=bnd.atom2, blist=blist: x != bnd and x.atom1 == at2 or x.atom2 == at2, blist) #finally, return the other atom in this bond bnd.nextbond2 = z2[0] if bnd.nextbond2 == bnd: bnd.nextbond2 = z2[1] #neighbor2 = self._getnxtAtom(b.atom2,b.nextbond2) neighbor2 = bnd.nextbond2.atom1 if neighbor2 == bnd.atom2: neighbor2 = bnd.nextbond2.atom2 bnd.next2 = neighbor2 #next have to check whether the normals are parallel #check each pair in each bond, how to keep track?? #have to get normal at b's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for bnd in blist: p = bnd.nrms psize = bnd.nrmsize q = bnd.nextbond2.nrms qsize = bnd.nextbond2.nrmsize #theta is the critical test for planarity: #if angle between 2 nrms is 0, atoms are planar #NB>test is comparing theta,cos(angle), w/zero bnd.theta = Numeric.dot(p, q) / (psize * qsize) #NB: REPEAT STUFF FROM HERE TO THE END IF aromaticCutOff changes ct = 0 for bnd in blist: #these are values for the default 7.5degrees: #if theta>=0.997 or theta<=-0.997: #print bnd.atom1.name, '-', bnd.atom2.name, '->', bnd.theta if bnd.theta >= cutoffValue or bnd.theta <= -cutoffValue: bnd.posAromatic = 1 ct = ct + 1 else: bnd.posAromatic = 0 #print ' posAromatic=', bnd.posAromatic #after checking all the bonds in current cycle, compare #posAromatic w/number if ct == len(blist): #print ctr," cycle is aromatic" #NB: only C=C bonds are considered aromatic # could change the name and autodock_element here.... for bnd in blist: # THIS IS WRONG!!! #if bnd.atom1.element=='C' and bnd.atom2.element=='C': # aromaticBnds.append(bnd) aromaticBnds.append(bnd) ctr = ctr + 1 #print "len(aromaticBnds)=", len(aromaticBnds) #for b in aromaticBnds: # print b.atom1.name, '-', b.atom2.name return aromaticBnds