def buildCloseContactAtoms(self, percentCutoff, ligand, comment="USER AD> "): pairDict = self.distanceSelector.select(ligand.allAtoms, self.macro_atoms, percentCutoff=percentCutoff) self.pairDict = pairDict #reset here lig_close_ats = AtomSet() macro_close_ats = AtomSet() cdict = {} for k,v in list(pairDict.items()): if len(v): cdict[k] = 1 for at in v: if at not in macro_close_ats: cdict[at] = 1 closeAtoms = AtomSet(list(cdict.keys())) lig_close_ats = closeAtoms.get(lambda x: x.top==ligand).uniq() #ligClAtStr = lig_close_ats.full_name() ligClAtStr = comment + "lig_close_ats: %d\n" %( len(lig_close_ats)) if len(lig_close_ats): ligClAtStr += comment + "%s\n" %( lig_close_ats.full_name()) macro_close_ats = closeAtoms.get(lambda x: x in self.macro_atoms).uniq() macroClAtStr = comment + "macro_close_ats: %d\n" %( len(macro_close_ats)) if len(macro_close_ats): macroClAtStr += comment + "%s\n" %( macro_close_ats.full_name()) #macroClAtStr = "macro_close_ats: " + len(macro_close_ats)+"\n" +macro_close_ats.full_name() rdict = self.results rdict['lig_close_atoms'] = lig_close_ats rdict['macro_close_atoms'] = macro_close_ats if self.verbose: print("macroClAtStr=", macroClAtStr) if self.verbose: print("ligClAtStr=", ligClAtStr) if self.verbose: print("returning "+ macroClAtStr + '==' + ligClAtStr) return macroClAtStr , ligClAtStr
def filterAcceptors(self, accAts): ntypes = ['Npl', 'Nam'] npls = accAts.get(lambda x, ntypes=ntypes: x.babel_type=='Npl') nams = accAts.get(lambda x, ntypes=ntypes: x.babel_type=='Nam') #nAts = accAts.get(lambda x, ntypes=ntypes: x.babel_type in ntypes) restAts = accAts.get(lambda x, ntypes=ntypes: x.babel_type not in ntypes) if not restAts: restAts = AtomSet([]) #if nAts: if npls: #for at in nAts: for at in npls: s = 0 for b in at.bonds: if b.bondOrder=='aromatic': s = s + 2 else: s = s + b.bondOrder #if s<3: #apparently this is wrong if s<4: restAts.append(at) if nams: #for at in nAts: for at in nams: s = 0 for b in at.bonds: if b.bondOrder=='aromatic': s = s + 2 else: s = s + b.bondOrder #s = s + b.bondOrder if s<3: restAts.append(at) return restAts
def get_atoms(mol, list_of_indicies, names_to_use=['N','CA','C'], verbose=False): if verbose: print "in get_atoms with list of indicies:" print list_of_indicies if not len(list_of_indicies): raise 'invalid input: list of indicies is empty!' atoms = AtomSet() num_res = 0 for item in list_of_indicies: first, second = item #check for valid index and for end of chain max_index = len(mol.chains.residues)-1 assert first<=max_index, 'invalid start of residue range' assert second<=max_index, 'invalid end of residue range' assert second>=first, 'second index cannot be smaller than first' if second==max_index: #ie mol.chains.residues[second]==mol.chains.residues[-1]: these_res = mol.chains.residues[first:] else: these_res = mol.chains.residues[first:second+1] if verbose: print "Adding %3d residues " %(len(these_res)), num_res+=len(these_res) if verbose: print "Now there are %d residues total" %(num_res) for r in these_res: for n in names_to_use: atoms.append( r.atoms.get(n)[0]) assert len(atoms), 'invalid input: lists of indicies did not correspond to any residues!' if verbose: print 'returning %d atoms' %(len(atoms)) return atoms
def createPairs(self, refnames, mobnames, slice, choice): # This is where the atom pairs are created # Get the ref atom set refAtms = AtomSet([]) mobAtms = AtomSet([]) for name in refnames: refnod = self.refNodes[name] atms = refnod.findType(Atom) refAtms = refAtms + atms for name in mobnames: mobnod = self.mobNodes[name] atms = mobnod.findType(Atom) mobAtms = mobAtms + atms # Now apply the filters to the sets if choice: refFiltAtms = refAtms.get(self.filters[choice]) mobFiltAtms = mobAtms.get(self.filters[choice]) if not len(refFiltAtms) == len(mobFiltAtms): #print 'slicing', slice self.warningMsg("the two sets of atoms needs to be of the same length") return ebn = self.cmdForms['pairs'].descr.entryByName lc = ebn['newpairs']['widget'] for refatm, mobatm in map(None, refFiltAtms, mobFiltAtms): #self.pairs.append((refatm, mobatm)) pairName = refatm.full_name() + '---' + mobatm.full_name() self.newPairs[pairName]=(refatm,mobatm) lc.add((pairName, None))
def get_atoms(mol, list_of_indicies, names_to_use=['N', 'CA', 'C'], verbose=False): if verbose: print("in get_atoms with list of indicies:") print(list_of_indicies) if not len(list_of_indicies): raise Exception('invalid input: list of indicies is empty!') atoms = AtomSet() num_res = 0 for item in list_of_indicies: first, second = item #check for valid index and for end of chain max_index = len(mol.chains.residues) - 1 assert first <= max_index, 'invalid start of residue range' assert second <= max_index, 'invalid end of residue range' assert second >= first, 'second index cannot be smaller than first' if second == max_index: #ie mol.chains.residues[second]==mol.chains.residues[-1]: these_res = mol.chains.residues[first:] else: these_res = mol.chains.residues[first:second + 1] if verbose: print("Adding %3d residues " % (len(these_res)), end=' ') num_res += len(these_res) if verbose: print("Now there are %d residues total" % (num_res)) for r in these_res: for n in names_to_use: atoms.append(r.atoms.get(n)[0]) assert len( atoms ), 'invalid input: lists of indicies did not correspond to any residues!' if verbose: print('returning %d atoms' % (len(atoms))) return atoms
def getCations(self, atoms): #select atoms in ARG and LYS residues arg_cations = atoms.get(lambda x: (x.parent.type=='ARG' and \ x.name in ['CZ'])) lys_cations = atoms.get(lambda x: (x.parent.type=='LYS' and \ x.name in ['NZ', 'HZ1', 'HZ2', 'HZ3'])) #select any positively-charged metal ions... cannot include CA here metal_cations = atoms.get(lambda x: x.name in ['Mn','MN', 'Mg',\ 'MG', 'FE', 'Fe', 'Zn', 'ZN']) ca_cations = atoms.get( lambda x: x.name in ['CA', 'Ca'] and x.parent.type == 'CA') cations = AtomSet() #cations.extend(arg_cations) for a in arg_cations: cations.append(a) #cations.extend(lys_cations) for a in lys_cations: cations.append(a) #cations.extend(metal_cations) for a in metal_cations: cations.append(a) #cations.extend(ca_cations) for a in ca_cations: cations.append(a) return cations
def getAtoms(self, bnds): ats0 = AtomSet() for b in bnds: ats0.append(b.atom1) ats0.append(b.atom2) d = {} for a in ats0: d[a] = 0 return AtomSet(d.keys())
def getAtoms(self,bnds): ats0 = AtomSet() for b in bnds: ats0.append(b.atom1) ats0.append(b.atom2) d = {} for a in ats0: d[a] = 0 return AtomSet(d.keys())
def doit(self, bonds): global var var=1 ats = AtomSet([]) for bond in bonds: ats.append(bond.atom1) ats.append(bond.atom2) self.vf.removeBonds(bond.atom1, bond.atom2) var=0 self.vf.GUI.VIEWER.Redraw()
def checkAromatics(self): """ checkAromatics """ #this depends on userPref useProteinAromaticList if not len(self.cyclebonds): self.aromaticCs = AtomSet() return "" if self.isPeptide and self.useProteinAromaticList: self.aromaticCs = self.getPeptideAromatics() return "" if self.isPeptide: self.getPeptideBondDict() else: self.getLigandBondDict() counter = 0 while counter < self.cyclecount: counter = counter + 1 blist = self.bondDict[counter] for item in blist: at = item.atom1 self._getAdjAtom(item, blist) #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 result = self._getNormal(item) item.nrmsize = result[0] item.nrms = result[1] #next find the other bond w/atom2: z2 = list( filter(lambda x, item=item, at2=item.atom2, blist=blist: x != item and x.atom1 == at2 or x.atom2 == at2, blist)) #finally, return the other atom in this bond item.nextbond2 = z2[0] if item.nextbond2 == item: item.nextbond2 = z2[1] neighbor2 = self._getnxtAtom(item.atom2, item.nextbond2) item.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 item's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for item in blist: p = item.nrms psize = item.nrmsize q = item.nextbond2.nrms qsize = item.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 item.theta = numpy.dot(p, q) / (psize * qsize) for p in ['next1', 'next2', 'nextbond', 'nextbond2']: delattr(item, p) self.updateAromatics(self.aromaticCutOff) msg = ' -found ' + str(len(self.aromaticCs)) + ' aromatic carbons\n' return msg
def onRemoveObjectFromViewer(self, mol): lenAts = len(self.atomList) #if cmd has no atoms on its list, nothing to do if not lenAts: return #remove any atoms which are being deleted from viewer self.atomList = AtomSet(self.atomList) - mol.allAtoms #if some have been removed, do an update if lenAts != len(self.atomList): self.update() self.extslider.set(0)
def doit(self, bonds): global var var = 1 ats = AtomSet([]) for bond in bonds: ats.append(bond.atom1) ats.append(bond.atom2) self.vf.removeBonds(bond.atom1, bond.atom2) var = 0 if self.vf.hasGui: self.vf.GUI.VIEWER.Redraw()
def getPeptideAromatics(self): atSet = AtomSet() allAts = self.allAtoms arom_ats = allAts.get(lambda x, l = pep_aromList:\ x.parent.type+'_'+x.name in l) if not arom_ats: return AtomSet([]) for at in arom_ats: at.name = 'A' + at.name[1:] at.autodock_element = 'A' #print 'returning ', len(arom_ats), ' arom_ats' return arom_ats
def pickedVerticesToAtoms(self, geom, vertInd): """Function called to convert a picked vertex into an atom""" # this function gets called when a picking or drag select event has # happened. It gets called with a geometry and the list of vertex # indices of that geometry that have been selected. # This function is in charge of turning these indices into an AtomSet chain = geom.chain l = [] for vi in vertInd: resInd = self.getResInd(vi, chain) l.append(chain.residues[resInd].atoms[0]) return AtomSet(AtomSet(l))
def checkBonds(self): """ checkBonds """ msg = "" #print self.name, ':' nphs = AtomSet() if len(self.nphs) and self.autoMergeNPHS: newmsg, nphs = self.mergeNPHS() msg = msg + newmsg bc = self.bondClassifier bonds = self.chains.residues.atoms.bonds[0] for b in bonds: b.activeTors = 0 b.possibleTors = 0 b.leaf = 0 #FIX THIS: #if isPeptide, don't get cycles this way #if self.isPeptide: #cycleSelector = bc['cycles'] #del bc['cycles'] results = bc.classify(bonds) #if self.isPeptide: #bc['cycles'] = cycleSelector #results['cycles'] = self.getPeptideBondDict() #for k,v in results.items(): # print k,' = ', len(v) self.rotatable = results['rotatable'] self.torscount = len(self.rotatable) self.possible_torscount = self.torscount for b in self.rotatable: b.activeTors = 1 b.possibleTors = 1 for b in results['leaf']: b.leaf = 1 for b in results['cycle']: b.incycle = 1 hydrogenRotators = results['hydrogenRotators'] self.hydrogenRotators = hydrogenRotators self.TORSDOF = self.torscount - len(hydrogenRotators) ptAts = bc.dict['rotatable'].getAtoms(self.rotatable) d = {} for a in ptAts: d[a] = 0 self.pTatomset = AtomSet(list(d.keys())) #print 'len(pTatomset=', len(self.pTatomset) self.leafbonds = results['leaf'] self.pepbackbonds = results['ppbb'] self.amidebonds = results['amide'] self.cyclebonds = results['cycle'] return msg, nphs
def doit(self, ats): if len(ats) > 2: if len(self.atomList): atSet = ats + self.atomList else: atSet = ats parent = atSet[0].parent parent.buildBondsByDistanceOnAtoms(atSet) self.atomList = AtomSet([]) self.update(True) else: lenAts = len(self.atomList) last = None if lenAts: last = self.atomList[-1] top = self.atomList[0].top for at in ats: #check for repeats of same atom if lenAts and at == last: continue #lenAts = len(self.atomList) #if lenAts and at==self.atomList[-1]: # continue if lenAts and at.top != self.atomList[-1].top: msg = "intermolecular bond to %s disallowed" % ( at.full_name()) self.warningMsg(msg) self.atomList.append(at) self.undoAtList.append(at) lenAts = len(self.atomList) self.update(True) #if only have one atom, there is nothing else to do if lenAts < 2: return #now build bonds between pairs of atoms atSet = self.atomList if lenAts % 2 != 0: atSet = atSet[:-1] #all pairs of atoms will be bonded #so keep only the last one self.atomList = atSet[-1:] lenAts = lenAts - 1 else: self.vf.labelByExpression(self.atomList, negate=1, topCommand=0) self.atomList = AtomSet([]) for i in range(0, lenAts, 2): at1 = atSet[i] at2 = atSet[i + 1] self.vf.addBonds(at1, at2, origin='UserDefined', topCommand=0) self.update(True)
def superimpose_cb(self, event=None): if len(self.newPairs) >= 4 : # Need at least 4 pairs of atoms to do the superimposition setAtm1 = AtomSet(map(lambda x: x[0], self.newPairs.values())) setAtm2 = AtomSet(map(lambda x: x[1], self.newPairs.values())) if len(setAtm1) != len(setAtm2): message = ' ERROR: the 2 sets of atoms are not of the length\nthe superimposition cannot be performed. ' self.warningMsg(msg) return self.vf.superimposeAtoms(setAtm1, setAtm2) self.supcb = 1
def checkForPossibleH(self, ats, blen): # @@FIX THIS: WHAT IS THE POINT OF THIS??? # check that if at has all bonds, at least one is to a hydrogen # have to do this by element?? probAts = AtomSet(ats.get(lambda x, blen=blen: len(x.bonds) == blen)) # probOAts = ats.get(lambda x, blen=blen: len(x.bonds)==blen) # probSAts = ats.get(lambda x, blen=blen: len(x.bonds)==blen) if probAts: rAts = AtomSet([]) for at in probAts: if not len(at.findHydrogens()): rAts.append(at) if len(rAts): ats = ats.subtract(rAts) return ats
def checkForPossibleH(self, ats, blen): #@@FIX THIS: WHAT IS THE POINT OF THIS??? #check that if at has all bonds, at least one is to a hydrogen # have to do this by element?? probAts = AtomSet(ats.get(lambda x, blen=blen: len(x.bonds)==blen)) #probOAts = ats.get(lambda x, blen=blen: len(x.bonds)==blen) #probSAts = ats.get(lambda x, blen=blen: len(x.bonds)==blen) if probAts: rAts = AtomSet([]) for at in probAts: if not len(at.findHydrogens()): rAts.append(at) if len(rAts): ats = ats.subtract(rAts) return ats
def superimpose_cb(self): refAtoms = AtomSet() mobAtoms = AtomSet() for pair in self.newPairs.values(): refAtoms.append(pair[0]) mobAtoms.append(pair[1]) apply(self.doitWrapper, (refAtoms, mobAtoms), {})
def getHBAcceptors(self, ats, acceptorList): #print "getHBAcceptors: acceptorList=", acceptorList #getHBAcceptors sp2 = [] sp3 = [] for item in sp2Acceptors: if item in acceptorList: sp2.append(item) for item in sp3Acceptors: if item in acceptorList: sp3.append(item) dAts2 = AtomSet(ats.get(lambda x, l=sp2: x.babel_type in l)) if dAts2: dAts2 = self.filterAcceptors(dAts2) dAts3 = AtomSet(ats.get(lambda x, l=sp3: x.babel_type in l)) return dAts2, dAts3
def doit(self, nodes, display=False): # Get the molecules and the atomSets per molecules in the set of nodes. molecules, atomSets = self.vf.getNodesByMolecule(nodes, Atom) # Loop over the molecules and the sets of atoms for mol, atm in map(None, molecules, atomSets): if self.hasBhtree: mol.buildBondsByDistance() else: # Need to build the bonds in a chain so loop over the chains. for chain in mol.chains: atmInChain = AtomSet( filter(lambda x, name=chain.id: x.parent.parent.id == name, atm)) if not len(atmInChain): continue residues = atmInChain.parent.uniq() residues.sort() residues[0].buildBondsByDistance() for ind in xrange(len(residues) - 1): res1 = residues[ind] res2 = residues[ind + 1] res2.buildBondsByDistance() chain.connectResidues(res1, res2) if display: # when we call it from the GUI we want the result to be displayed self.vf.displayLines(nodes, topCommand=0)
def doit(self, atom1, atom2): #Have to find the bond first theBond = None for b in atom1.bonds: at2 = b.atom1 if at2 == atom1: at2 = b.atom2 if at2 == atom2: #remove this bond theBond = b atom2.bonds.remove(theBond) #this may not be possible atom1.bonds.remove(theBond) atom1.parent.hasBonds = 0 if atom2.parent != atom1.parent: atom2.parent.hasBonds = 0 if atom1.parent.parent: atom1.parent.parent.hasBonds = 0 if atom2.parent.parent: atom2.parent.parent.hasBonds = 0 break if not theBond: from warnings import warn warn('bond not found %s-%s' % (atom1, atom2)) return 'ERROR' else: event = EditAtomsEvent('coords', AtomSet([atom1, atom2])) self.vf.dispatchEvent(event)
def setupUndoAfter(self, ats, angle,**kw): #no atoms, <4 atoms, aSet = AtomSet(self.atomList) self.undoMenuString = self.name if len(self.atomList)==0: undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()' elif len(self.atomList)<4: #need to step back here undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()' elif self.origValue==self.oldValue: return else: restoreAngle = self.origValue self.undoNow = 1 undoCmd = 'self.setTorsionGC(\''+ aSet.full_name()+ '\',' + str(restoreAngle) + ', topCommand=0)' self.vf.undo.addEntry((undoCmd), (self.name))
def __call__(self, atom1, atom2, bondOrder=1, origin='UserDefined', **kw): """None<-addBonds(atom1, atom2) \natom1 : first atom \natom2 : second atom \nbondOrder : Integer specifying the bondOrder of the bond that is going to be created between atom1 and atom2.The bondOrder by default is 1. \norigin : string describing how bond was specified""" ats = self.vf.expandNodes(atom1) if not len(ats): return 'ERROR' at1 = ats[0] ats = self.vf.expandNodes(atom2) if not len(ats): return 'ERROR' at2 = ats[0] if at1.top != at2.top: msg = "intermolecular bond between %s and %s \ disallowed" % (at1.full_name(), at2.full_name()) self.warningMsg(msg) return 'ERROR' bnds = AtomSet([at1, at2]).bonds[0] if len(bnds): msg = " bond between %s and %s already \ exists" % (at1.full_name(), at2.full_name()) return 'ERROR' kw['bondOrder'] = bondOrder kw['origin'] = origin return apply(self.doitWrapper, (at1, at2), kw)
def stepBack(self, event=None): items = self.historyList.curselection() if len(items) == 0: return try: items = map(int, items) except ValueError: pass thisTA = self.TAHdata.torslist[items[0]] ####last angle is thisTA.angleList[-1] if len(thisTA.angleList) > 1: last = thisTA.angleList[-1] lastIndex = thisTA.angleList.index(last) thisTA.angleList = thisTA.angleList[:lastIndex] last = thisTA.angleList[-1] else: last = thisTA.angleList[0] newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\ thisTA.atom4]) #reset self.molecule self.atomList = [] self.molecule = newAts[0].top self.doit(newAts, last) #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.drawTransformedAngle() #self.updatespheres(items[0]) newstring = "" for item in thisTA.angleList: newstring = newstring + " " + "%5.3f" % item self.newAngList.set(newstring) self.extslider.set(last, 0) #IS THIS ENOUGH in order to create correct log? self.mouseUp()
def getObjects(self, column): # return a list of objects associated with this node and possibly # other seleted nodes. For selection we return a list for each type # ( i.e. Atom, Residue, etc..) # if the node is selected, collect object from all other selected nodes resultAtoms = AtomSet([]) resultResidues = ResidueSet([]) resultChains = ChainSet([]) resultMolecules = MoleculeSet([]) buttonValue = self.chkbtVar[column].get() if self.selected: for node in self.tree.list_selected: node.chkbtVar[column].set(buttonValue) result = node.getNodes(column) obj = result[0] if isinstance(obj, Atom): resultAtoms += result elif isinstance(obj, Residue): resultResidues += result elif isinstance(obj, Chain): resultChains += result elif isinstance(obj, Molecule) or isinstance(obj, Protein): resultMolecules += result result = [] if len(resultAtoms): result.append(resultAtoms) if len(resultResidues): result.append(resultResidues) if len(resultChains): result.append(resultChains) if len(resultMolecules): result.append(resultMolecules) return result else: return [self.getNodes(column)]
def getTransformedCoords(self, atom): # when there is no viewer, the geomContainer is None if not atom.top.geomContainer: return atom.coords g = atom.top.geomContainer.geoms['master'] c = self.vf.transformedCoordinatesWithInstances(AtomSet([atom])) return Numeric.array(c[0], 'f')
def write_maps(self, filestem=None, fld=1, xyz=1): # now create the atom maps if filestem is None: filestem = self.receptor.name for element in self.atom_types: # set atom.element to the element self.atom.element = element self.atom.autodock_element = element try: self.atom_map_scorer.terms[4][0].set_vina_types( AtomSet(self.atom)) except: self.atom.is_hydrophobic = self.atom.element in [ 'A', 'C', 'HD' ] # score it score_array = self.atom_map_scorer.get_score_array() # create filename and write it filename = filestem + "." + element + ".map" self.write_grid_map(score_array, filename) # now possibly write the fld file if fld: fld_filename = filestem + ".maps.fld" self.write_maps_fld(fld_filename) # now possibly write the xyz file if xyz: xyz_filename = self.receptor.name + ".maps.xyz" self.write_xyz_file(xyz_filename)
def doit(self, Klass, KlassSet=None): if type(Klass) == types.StringType: if Klass in self.levelDict.keys(): Klass = self.levelDict[Klass] else: msg = Klass + "string does not map to a valid level" self.warningMsg(msg) return "ERROR" if Klass is Protein: Klass = Molecule if len(self.vf.selection): self.vf.selection = self.vf.selection.findType(Klass).uniq() else: if Klass == Molecule: self.vf.selection = MoleculeSet([]) elif Klass == Chain: self.vf.selection = ChainSet([]) elif Klass == Residue: self.vf.selection = ResidueSet([]) elif Klass == Atom: self.vf.selection = AtomSet([]) self.vf.selectionLevel = Klass self.vf.ICmdCaller.setLevel(Klass, KlassSet=None) if self.vf.hasGui: col = self.vf.ICmdCaller.levelColors[Klass.__name__] c = (col[0] / 1.5, col[1] / 1.5, col[2] / 1.5) self.vf.GUI.pickLabel.configure(background=TkColor(c)) msg = '%d %s(s)' % (len( self.vf.selection), self.vf.selectionLevel.__name__) self.vf.GUI.pickLabel.configure(text=msg) if hasattr(self.vf, 'select'): self.vf.select.updateSelectionIcons() self.levelVar.set(self.vf.selectionLevel.__name__)
def doit(self, ats): if len(ats)>2: if len(self.atomList): atSet = ats + self.atomList else: atSet = ats parent = atSet[0].parent parent.buildBondsByDistanceOnAtoms(atSet) self.atomList = AtomSet([]) self.update(True) else: lenAts = len(self.atomList) last = None if lenAts: last = self.atomList[-1] top = self.atomList[0].top for at in ats: #check for repeats of same atom if lenAts and at==last: continue #lenAts = len(self.atomList) #if lenAts and at==self.atomList[-1]: # continue if lenAts and at.top!=self.atomList[-1].top: msg = "intermolecular bond to %s disallowed"%(at.full_name()) self.warningMsg(msg) self.atomList.append(at) self.undoAtList.append(at) lenAts = len(self.atomList) self.update(True) #if only have one atom, there is nothing else to do if lenAts<2: return #now build bonds between pairs of atoms atSet = self.atomList if lenAts%2!=0: atSet = atSet[:-1] #all pairs of atoms will be bonded #so keep only the last one self.atomList = atSet[-1:] lenAts = lenAts -1 else: self.vf.labelByExpression(self.atomList, negate=1, topCommand=0) self.atomList = AtomSet([]) for i in range(0, lenAts, 2): at1 = atSet[i] at2 = atSet[i+1] self.vf.addBonds(at1, at2, origin='UserDefined', topCommand=0) self.update(True)
def setupUndoAfter(self, ats, angle, **kw): #no atoms, <4 atoms, aSet = AtomSet(self.atomList) self.undoMenuString = self.name if len(self.atomList) == 0: undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()' elif len(self.atomList) < 4: #need to step back here undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()' elif self.origValue == self.oldValue: return else: restoreAngle = self.origValue self.undoNow = 1 undoCmd = 'self.setTorsionGC(\'' + aSet.full_name() + '\',' + str( restoreAngle) + ', topCommand=0)' self.vf.undo.addEntry((undoCmd), (self.name))
def removeNeighbors(self, atDict): #filter out at-itself and at-bondedat up to 1:4 #NB keys could be hydrogens OR donors for at in atDict.keys(): closeAts = atDict[at] bondedAts = AtomSet([]) for b in at.bonds: ###at2 = b.neighborAtom(at) at2 = b.atom1 if id(at2) == id(at): at2 = b.atom2 bondedAts.append(at2) #9/13 remove this: ##also remove 1-3 for b2 in at2.bonds: at3 = b2.atom1 if id(at3) == id(at2): at3 = b.atom2 #at3 = b2.neighborAtom(at2) if id(at3) != id(at): bondedAts.append(at3) #for b3 in at3.bonds: #at4 = b2.neighborAtom(at3) #if at4!=at and at4!=at2: #bondedAts.append(at4) bondedAts = bondedAts.uniq() goodAts = [] for i in range(len(closeAts)): cAt = closeAts[i] if cAt not in bondedAts: goodAts.append(cAt) if len(goodAts): atDict[at] = goodAts else: del atDict[at] return atDict
def buildCloseContactAtoms(self, percentCutoff, ligand, comment="USER AD> "): pairDict = self.distanceSelector.select(ligand.allAtoms, self.macro_atoms, percentCutoff=percentCutoff) self.pairDict = pairDict #reset here lig_close_ats = AtomSet() macro_close_ats = AtomSet() cdict = {} for k,v in pairDict.items(): if len(v): cdict[k] = 1 for at in v: if at not in macro_close_ats: cdict[at] = 1 closeAtoms = AtomSet(cdict.keys()) lig_close_ats = closeAtoms.get(lambda x: x.top==ligand).uniq() #ligClAtStr = lig_close_ats.full_name() ligClAtStr = comment + "lig_close_ats: %d\n" %( len(lig_close_ats)) if len(lig_close_ats): ligClAtStr += comment + "%s\n" %( lig_close_ats.full_name()) macro_close_ats = closeAtoms.get(lambda x: x in self.macro_atoms).uniq() macroClAtStr = comment + "macro_close_ats: %d\n" %( len(macro_close_ats)) if len(macro_close_ats): macroClAtStr += comment + "%s\n" %( macro_close_ats.full_name()) #macroClAtStr = "macro_close_ats: " + len(macro_close_ats)+"\n" +macro_close_ats.full_name() rdict = self.results rdict['lig_close_atoms'] = lig_close_ats rdict['macro_close_atoms'] = macro_close_ats if self.verbose: print "macroClAtStr=", macroClAtStr if self.verbose: print "ligClAtStr=", ligClAtStr if self.verbose: print "returning "+ macroClAtStr + '==' + ligClAtStr return macroClAtStr , ligClAtStr
def doit(self, ats): #DisplayStruts base class self.reset() hbats = AtomSet(ats.get(lambda x: hasattr(x, 'struts'))) if not hbats: self.warningMsg('no struts bonds found, please compute them') return 'ERROR' self.hats = hbats self.showAllHBonds()
def getHBDonors(self, ats, donorList): #getHBDonors sp2 = [] sp3 = [] for item in sp2Donors: if item in donorList: sp2.append(item) for item in sp3Donors: if item in donorList: sp3.append(item) dAts2 = ats.get(lambda x, l=sp2: x.babel_type in l) if not dAts2: dAts2 = AtomSet([]) else: dAts2 = self.checkForPossibleH(dAts2, 3) dAts3 = ats.get(lambda x, l=sp3: x.babel_type in l) if not dAts3: dAts3 = AtomSet([]) else: dAts3 = self.checkForPossibleH(dAts3, 4) return dAts2, dAts3
def onRemoveObjectFromViewer(self, obj): removeAts = AtomSet([]) for at in self.atomList: if at in obj.allAtoms: removeAts.append(at) self.atomList = self.atomList - removeAts removeAts = AtomSet([]) for at in self.undoAtList: if at in obj.allAtoms: removeAts.append(at) self.undoAtList = self.undoAtList - removeAts self.update()
def set_carbon_names(self, atoms, type): #set carbon names explicitly if not atoms or not len(atoms): return "ERROR: set_carbon_names called with no atoms" assert type in ['C','A'] if not hasattr(atoms, 'autodock_element'): atoms.autodock_element = atoms.element changed = AtomSet() for at in atoms: if at.element!='C': continue if at.autodock_element!=type: if self.rename: if len(at.name)>1: at.name = type + at.name[1:] else: at.name = type at.autodock_element = type changed.append(at) return changed
def set_carbon_names(self, atoms, type): #set carbon names explicitly if not atoms or not len(atoms): return "ERROR: set_carbon_names called with no atoms" assert type in ['C', 'A'] if not hasattr(atoms, 'autodock_element'): atoms.autodock_element = atoms.element changed = AtomSet() for at in atoms: if at.element != 'C': continue if at.autodock_element != type: if self.rename: if len(at.name) > 1: at.name = type + at.name[1:] else: at.name = type at.autodock_element = type changed.append(at) return changed
def buildHydrogenBonds(self, ligand, comment="USER AD> "): h_pairDict = self.hydrogen_bond_builder.build(ligand.allAtoms, self.macro_atoms) self.h_pairDict = h_pairDict #keys should be from lig, values from macro #sometimes are not...@@check this@@ h_results = {} for k, v in h_pairDict.items(): h_results[k] = 1 for at in v: h_results[at] = 1 all_hb_ats = AtomSet(h_results.keys()) #all d = self.results macro_hb_ats = d['macro_hb_atoms'] = all_hb_ats.get( lambda x: x.top == self.macro) self.macro_hb_ats = macro_hb_ats # process lig lig_hb_ats = d['lig_hb_atoms'] = all_hb_ats.get( lambda x: x in ligand.allAtoms) self.lig_hb_ats = lig_hb_ats outS = comment + "lig_hb_atoms : %d\n" % (len(lig_hb_ats)) for p in self.lig_hb_ats: #intD.results['lig_hb_atoms']: for hb in p.hbonds: if hasattr(hb, 'used'): continue if hb.hAt is not None: outS += comment + "%s,%s~%s\n" % (hb.donAt.full_name( ), hb.hAt.name, hb.accAt.full_name()) else: outS += comment + "%s~%s\n" % (hb.donAt.full_name(), hb.accAt.full_name()) hb.used = 1 #hsg1V:B:ARG8:NH2,HH22~clean: : INI 20:N5 #clean: : INI 20:O4,H3~hsg1V:B:ASP29:OD2 #clean: : INI 20:O4,H3~hsg1V:B:ASP29:OD2 #clean: : INI 20:N4,H3~hsg1V:B:GLY27:O #clean: : INI 20:O2,H2~hsg1V:B:ASP25:OD1 #macroHStr = self.macro.allAtoms.get(lambda x: hasattr(x, 'hbonds') and len(x.hbonds)).full_name() #ligHStr = ligand.allAtoms.get(lambda x: hasattr(x, 'hbonds') and len(x.hbonds)).full_name() #return macroHStr + '==' + ligHStr if self.verbose: print "buildHB returning:" print outS return outS
def onRemoveObjectFromViewer(self, mol): lenAts = len(self.atomList) #if cmd has no atoms on its list, nothing to do if not lenAts: return #remove any atoms which are being deleted from viewer self.atomList = AtomSet(self.atomList) - mol.allAtoms #if some have been removed, do an update if lenAts!=len(self.atomList): self.update() self.extslider.set(0)
def removeNeighbors(self, atDict): #filter out at-itself and at-bondedat up to 1:4 #NB keys could be hydrogens OR donors for at in atDict.keys(): closeAts = atDict[at] bondedAts = AtomSet([]) for b in at.bonds: ###at2 = b.neighborAtom(at) at2 = b.atom1 if id(at2)==id(at): at2 = b.atom2 bondedAts.append(at2) #9/13 remove this: ##also remove 1-3 for b2 in at2.bonds: at3 = b2.atom1 if id(at3)==id(at2): at3 = b.atom2 #at3 = b2.neighborAtom(at2) if id(at3)!=id(at): bondedAts.append(at3) #for b3 in at3.bonds: #at4 = b2.neighborAtom(at3) #if at4!=at and at4!=at2: #bondedAts.append(at4) bondedAts = bondedAts.uniq() goodAts = [] for i in range(len(closeAts)): cAt = closeAts[i] if cAt not in bondedAts: goodAts.append(cAt) if len(goodAts): atDict[at] = goodAts else: del atDict[at] return atDict
def checkAromatics(self): """ checkAromatics """ #this depends on userPref useProteinAromaticList if not len(self.cyclebonds): self.aromaticCs = AtomSet() return "" if self.isPeptide and self.useProteinAromaticList: self.aromaticCs = self.getPeptideAromatics() return "" if self.isPeptide: self.getPeptideBondDict() else: self.getLigandBondDict() counter = 0 while counter < self.cyclecount: counter = counter + 1 blist = self.bondDict[counter] for item in blist: at = item.atom1 self._getAdjAtom(item, blist) #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 result = self._getNormal(item) item.nrmsize = result[0] item.nrms = result[1] #next find the other bond w/atom2: z2 = filter(lambda x,item=item, at2=item.atom2, blist=blist:x!=item and x.atom1==at2 or x.atom2==at2, blist) #finally, return the other atom in this bond item.nextbond2 = z2[0] if item.nextbond2==item: item.nextbond2 = z2[1] neighbor2 = self._getnxtAtom(item.atom2,item.nextbond2) item.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 item's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for item in blist: p = item.nrms psize = item.nrmsize q = item.nextbond2.nrms qsize = item.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 item.theta = Numeric.dot(p,q)/(psize*qsize) for p in ['next1','next2','nextbond','nextbond2']: delattr(item, p) self.updateAromatics(self.aromaticCutOff) msg = ' -found '+ str(len(self.aromaticCs)) + ' aromatic carbons\n' return msg
def superimpose_cb(self): refAtoms = AtomSet() mobAtoms = AtomSet() for pair in self.newPairs.values(): refAtoms.append(pair[0]) mobAtoms.append(pair[1]) apply( self.doitWrapper, (refAtoms,mobAtoms), {} )
def buildHydrogenBonds(self, ligand, comment="USER AD> "): h_pairDict = self.hydrogen_bond_builder.build(ligand.allAtoms, self.macro_atoms) self.h_pairDict = h_pairDict #keys should be from lig, values from macro #sometimes are not...@@check this@@ h_results = {} for k, v in h_pairDict.items(): h_results[k] = 1 for at in v: h_results[at] = 1 all_hb_ats = AtomSet(h_results.keys()) #all d = self.results macro_hb_ats = d['macro_hb_atoms'] = all_hb_ats.get(lambda x: x.top==self.macro) self.macro_hb_ats = macro_hb_ats # process lig lig_hb_ats = d['lig_hb_atoms'] = all_hb_ats.get(lambda x: x in ligand.allAtoms) self.lig_hb_ats = lig_hb_ats outS = comment + "lig_hb_atoms : %d\n"%(len(lig_hb_ats)) for p in self.lig_hb_ats: #intD.results['lig_hb_atoms']: for hb in p.hbonds: if hasattr(hb, 'used'): continue if hb.hAt is not None: outS += comment + "%s,%s~%s\n"%(hb.donAt.full_name(), hb.hAt.name, hb.accAt.full_name()) else: outS += comment + "%s~%s\n"%(hb.donAt.full_name(), hb.accAt.full_name()) hb.used = 1 #hsg1V:B:ARG8:NH2,HH22~clean: : INI 20:N5 #clean: : INI 20:O4,H3~hsg1V:B:ASP29:OD2 #clean: : INI 20:O4,H3~hsg1V:B:ASP29:OD2 #clean: : INI 20:N4,H3~hsg1V:B:GLY27:O #clean: : INI 20:O2,H2~hsg1V:B:ASP25:OD1 #macroHStr = self.macro.allAtoms.get(lambda x: hasattr(x, 'hbonds') and len(x.hbonds)).full_name() #ligHStr = ligand.allAtoms.get(lambda x: hasattr(x, 'hbonds') and len(x.hbonds)).full_name() #return macroHStr + '==' + ligHStr if self.verbose: print "buildHB returning:" print outS return outS
def setAromaticCarbons(self, molecule, cutoff=None, debug=False): assert len(molecule.allAtoms.bonds[0]) if cutoff: if cutoff!=self.cutoff: old_aromCs = molecule.allAtoms.get(lambda x:\ (x.element=='C' and x.autodock_element=='A')) if old_aromCs is not None and len(old_aromCs)!=0: if debug: print "resetting ", len(old_aromCs), " prior aromCs" self.set_carbon_names(old_aromCs, 'C') self.cutoff = cutoff typed_atoms = molecule.allAtoms.get(lambda x: hasattr(x, 'autodock_element')) currentAromCs = AtomSet() if typed_atoms is not None and len(typed_atoms)==len(molecule.allAtoms): currentAromCs = molecule.allAtoms.get(lambda x: (x.element=='C' and x.autodock_element=='A')) if debug: if currentAromCs is not None and len(currentAromCs): print "now: ", len(currentAromCs) else: print "now: no aromCs" aromBnds = self.aromBndSel.select(molecule.allAtoms.bonds[0], self.cutoff) aromBndAts = self.aromBndSel.getAtoms(aromBnds) result = AtomSet() changed = AtomSet() if len(aromBndAts): aromCs = AtomSet(filter(lambda x: x.element=='C', \ aromBndAts)) aromCs = aromCs.uniq() if len(aromCs)>len(result): result = aromCs if debug: print "len(aromCs)=", len(aromCs) changed = self.set_carbon_names(aromCs, 'A') #if len(changed)>len(result): # result = changed #return result return changed
def getCations(self, atoms): #select atoms in ARG and LYS residues arg_cations = atoms.get(lambda x: (x.parent.type=='ARG' and \ x.name in ['CZ'])) lys_cations = atoms.get(lambda x: (x.parent.type=='LYS' and \ x.name in ['NZ', 'HZ1', 'HZ2', 'HZ3'])) #select any positively-charged metal ions... cannot include CA here metal_cations = atoms.get(lambda x: x.name in ['Mn','MN', 'Mg',\ 'MG', 'FE', 'Fe', 'Zn', 'ZN']) ca_cations = atoms.get(lambda x: x.name in ['CA', 'Ca'] and x.parent.type=='CA') cations = AtomSet() #cations.extend(arg_cations) for a in arg_cations: cations.append(a) #cations.extend(lys_cations) for a in lys_cations: cations.append(a) #cations.extend(metal_cations) for a in metal_cations: cations.append(a) #cations.extend(ca_cations) for a in ca_cations: cations.append(a) return cations
class LigandMixin(Subject): """ lfo adds capability to a protein/molecule to be used as a ligand in an AutoDock docking """ def setup(self, useProteinAromaticList=1, aromaticCutOff=7.5, maxtors=32, autoMergeNPHS=1): if self.chains[0].hasBonds==0: self.buildBondsByDistance() self.useProteinAromaticList = useProteinAromaticList self.aromaticCutOff = aromaticCutOff self.maxtors = 32 self.autoMergeNPHS = autoMergeNPHS self.bondClassifier = AutoDockBondClassifier() self.torsionTree = None self.message = "" self.torscount = 0 self.possible_torscount = 0 self.TORSDOF = 0 self.resKeys = q.keys() self.PdbqWriter = PdbqWriter() #should this be here? msg = 'initialized ' + self.name +':\n' #detect whether isPeptide msg += self.checkIsPeptide() #process charges msg += self.checkCharges() ##process hydrogens msg += self.checkHydrogens() #process bonds #this doesn't report anything??? newmsg, nphs = self.checkBonds() msg += newmsg #process aromaticCarbons msg += self.checkAromatics() return msg, nphs def checkIsPeptide(self): """ checkIsPeptide """ #check whether each restype is in std list #if so, self is a peptide resSet = self.chains.residues dict = {} for r in resSet: dict[r.type] = 0 for t in dict.keys(): if t not in self.resKeys: self.isPeptide = 0 return ' -it is not a peptide\n' #only get to this point if all #residue types were found self.isPeptide = 1 return ' -it is a peptide\n' def checkCharges(self): """ checkCharges """ msg = ' -already had charges' if hasattr(self, 'checked_charges'): return msg msg = "" needToAdd = 0 chargedAts = self.allAtoms.get(lambda x: hasattr(x, 'charge')) if not chargedAts: needToAdd = 1 elif len(chargedAts)!=len(self.allAtoms): needToAdd = 1 elif len(filter(lambda x:x.charge==0, chargedAts))==len(chargedAts): #this checks that each atom doesn't have charge=0 needToAdd = 1 #to add Kollman need to: # look up each atom's parent in q to get dict=q[at.parent.type] # find the atom's name in dict to get a charge # set atom._charges['Kollman'] to that charge # there are special problems with his, cys and termini # set allAtoms.chargeSet to 'Kollman' if needToAdd: if not hasattr(self, 'isPeptide'): msg = self.checkIsPeptide() if self.isPeptide: #self.checked_charges = 'needs Kollman' self.addKollman() self.checked_charges = 'has Kollman' #self.vf.addKollmanCharges(self, topCommand=0, log=0) msg = msg + ' -added Kollman charges\n' else: #self.checked_charges = 'needs gasteiger' self.computeGasteiger() self.checked_charges = 'has gasteiger' #self.vf.computeGasteiger(self, topCommand=0, log=0) msg = msg + ' -added gasteiger charges\n' else: self.checked_charges = 'has charges' msg = msg + ' -already had charges\n' # adt will have to add charges... AND check them #at this point, every atom has a charge and charges are not all 0k #have to have unit charges per residue #print 'calling checkMolCharges' #errCharge, resList = checkMolCharges(self, self.vf) #FIX THIS: need to add mechanism to adjust charges #gui to let user pick + change #or either change on first atom or spread over all #self.checked_charges = 1 #if added charges, msg will say which one #if did't add charges, msg will be 'ERROR' return msg def computeGasteiger(self): #to compute Gasteiger need to: # create an AtomHybridization() # call its assignHybridization method on self.allAtoms # create a Gasteiger() # call its compute method on self.allAtoms # THEN move gast_charge into _charges with gasteiger key # set allAtoms.chargeSet to 'gasteiger' # THEN delattr gast_charge from allAtoms allAts = self.allAtoms ah = AtomHybridization() ah.assignHybridization(allAts) Gast = Gasteiger() Gast.compute(allAts) gastCharges = [] for c in allAts.gast_charge: gastCharges.append(round(c, 3)) allAts.addCharges('gasteiger', gastCharges) del allAts.gast_charge allAts.chargeSet = 'gasteiger' def addKollman(self): #to add Kollman need to: # look up each atom's parent in q to get dict=q[at.parent.type] # find the atom's name in dict to get a charge # set atom._charges['Kollman'] to that charge # there are special problems with his, cys and termini # set allAtoms.chargeSet to 'Kollman' for a in self.allAtoms: dict = q.get(a.parent.type, {}) if len(dict): a._charges['Kollman'] = dict.get(a.parent.type, 0) else: a._charges['Kollman'] = 0 a.chargeSet = 'Kollman' def checkHydrogens(self): """ checkHydrogens """ #what if self doesn't have bonds if not self.chains[0].hasBonds: self.buildBondsByDistance() hs = self.allAtoms.get(lambda x: x.element=='H') self.nphs = AtomSet() if not hs: msg = ' -no polar hydrogens found!\n' if hs: nphs = hs.get(lambda x: x.bonds[0].atom1.element=='C' or \ x.bonds[0].atom2.element=='C') if nphs: self.nphs = nphs msg = ' -found ' + str(len(self.nphs)) + ' nonpolar hydrogens\n' else: msg = ' -no nonpolar hydrogens\n' return msg def mergeNPHS(self): lenNPHS = len(self.nphs) if not lenNPHS: return nphs = self.nphs atLen = len(self.allAtoms) self.allAtoms = self.allAtoms - nphs #first add charge to nph's heavy atom chList = nphs[0]._charges.keys() if not len(chList): print 'no charges present' return 'XXX' #check that all nphs have a certain kind of charge for at in nphs: chs = at._charges.keys() for c in chList: if c not in chs: chList.remove(c) if len(chList): for chargeSet in chList: for h in nphs: b = h.bonds[0] c = b.atom1 if c==h: c = b.atom2 c._charges[chargeSet] = c._charges[chargeSet] + h._charges[chargeSet] #next delete nphs for h in nphs: b = h.bonds[0] c = b.atom1 if c==h: c = b.atom2 c.bonds.remove(b) h.bonds = BondSet() h.parent.remove(h) #nb: #these don't show up in deleteMol.getFreeMemoryInformation del h self.nphs = AtomSet() return ' and merged them\n', nphs def checkBonds(self): """ checkBonds """ msg = "" #print self.name, ':' nphs = AtomSet() if len(self.nphs) and self.autoMergeNPHS: newmsg, nphs = self.mergeNPHS() msg = msg + newmsg bc = self.bondClassifier bonds = self.chains.residues.atoms.bonds[0] for b in bonds: b.activeTors = 0 b.possibleTors = 0 b.leaf = 0 #FIX THIS: #if isPeptide, don't get cycles this way #if self.isPeptide: #cycleSelector = bc['cycles'] #del bc['cycles'] results = bc.classify(bonds) #if self.isPeptide: #bc['cycles'] = cycleSelector #results['cycles'] = self.getPeptideBondDict() #for k,v in results.items(): # print k,' = ', len(v) self.rotatable = results['rotatable'] self.torscount = len(self.rotatable) self.possible_torscount = self.torscount for b in self.rotatable: b.activeTors = 1 b.possibleTors = 1 for b in results['leaf']: b.leaf = 1 for b in results['cycle']: b.incycle = 1 hydrogenRotators = results['hydrogenRotators'] self.hydrogenRotators = hydrogenRotators self.TORSDOF = self.torscount - len(hydrogenRotators) ptAts = bc.dict['rotatable'].getAtoms(self.rotatable) d = {} for a in ptAts: d[a] = 0 self.pTatomset = AtomSet(d.keys()) #print 'len(pTatomset=', len(self.pTatomset) self.leafbonds = results['leaf'] self.pepbackbonds = results['ppbb'] self.amidebonds = results['amide'] self.cyclebonds = results['cycle'] return msg, nphs def checkAromatics(self): """ checkAromatics """ #this depends on userPref useProteinAromaticList if not len(self.cyclebonds): self.aromaticCs = AtomSet() return "" if self.isPeptide and self.useProteinAromaticList: self.aromaticCs = self.getPeptideAromatics() return "" if self.isPeptide: self.getPeptideBondDict() else: self.getLigandBondDict() counter = 0 while counter < self.cyclecount: counter = counter + 1 blist = self.bondDict[counter] for item in blist: at = item.atom1 self._getAdjAtom(item, blist) #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 result = self._getNormal(item) item.nrmsize = result[0] item.nrms = result[1] #next find the other bond w/atom2: z2 = filter(lambda x,item=item, at2=item.atom2, blist=blist:x!=item and x.atom1==at2 or x.atom2==at2, blist) #finally, return the other atom in this bond item.nextbond2 = z2[0] if item.nextbond2==item: item.nextbond2 = z2[1] neighbor2 = self._getnxtAtom(item.atom2,item.nextbond2) item.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 item's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for item in blist: p = item.nrms psize = item.nrmsize q = item.nextbond2.nrms qsize = item.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 item.theta = Numeric.dot(p,q)/(psize*qsize) for p in ['next1','next2','nextbond','nextbond2']: delattr(item, p) self.updateAromatics(self.aromaticCutOff) msg = ' -found '+ str(len(self.aromaticCs)) + ' aromatic carbons\n' return msg def updateAromatics(self, cutoff): self.aromaticCutOff = cutoff #cutoff = self.aromaticCutOff cutoffValue = math.cos(cutoff*math.pi/180.) aromaticCs = AtomSet([]) atD = {} #to keep from overwriting names of aromatic carbons at #junctions of rings use this klug for blist in self.bondDict.values(): for item in blist: item.atom1.setThisTime = 0 item.atom2.setThisTime = 0 for blist in self.bondDict.values(): ct = 0 for item in blist: #these are values for the default 7.5degrees: #if theta>=0.997 or theta<=-0.997: if item.theta>=cutoffValue or item.theta<=-cutoffValue: item.posAromatic = 1 ct = ct + 1 else: item.posAromatic = 0 #after checking all the bonds in current cycle, compare #posAromatic w/number if ct==len(blist): #and change the name and autodock_element here.... for b in blist: at1 = b.atom1 at2 = b.atom2 if at1.element=='C': at1.name = 'A' + at1.name[1:] at1.autodock_element = 'A' atD[at1] = 0 at1.setThisTime = 1 if at2.element=='C': at2.name = 'A' + at2.name[1:] at2.autodock_element = 'A' atD[at2] = 0 at2.setThisTime = 1 aromaticCs = AtomSet(atD.keys()) else: #if there were any aromatic carbons which no longer #meet the criteria, change them back for b in blist: at1 = b.atom1 at2 = b.atom2 if at1.name[0]=='A' and not at1.setThisTime: at2.autodock_element = 'C' at1.name = 'C' + at1.name[1:] if at2.name[0]=='A'and not at2.setThisTime: at2.autodock_element = 'C' at2.name = 'C' + at2.name[1:] #remove klug for blist in self.bondDict.values(): for item in blist: if hasattr(item.atom1, 'setThisTime'): delattr(item.atom1,'setThisTime') if hasattr(item.atom2, 'setThisTime'): delattr(item.atom2,'setThisTime') for a in aromaticCs: a.autodock_element = 'A' self.aromaticCs = aromaticCs def restoreCarbons(self): for a in self.aromaticCs: if len(a.name)==1: a.name = 'C' else: a.name = 'C' + a.name[1:] a.autodock_element = 'C' def nameAromatics(self): for a in self.aromaticCs: if len(a.name)==1: a.name = 'A' else: a.name = 'A' + a.name[1:] a.autodock_element = 'A' def addAromatic(self, at): if at.element!='C': print at.name, ' is not a carbon' return 'ERROR' if at in self.aromaticCs: print at.name, ' is already in aromatic set' return 'ERROR' at.autodock_element = 'A' self.aromaticCs.append(at) print at.name, ' added to aromatic set' def removeAromatic(self, at): if at not in self.aromaticCs: print at.name, ' is not in aromatic set' return 'ERROR' self.aromaticCs.remove(at) at.autodock_element = 'C' print at.name, ' removed from aromatic set' def getPeptideAromatics(self): atSet = AtomSet() allAts = self.allAtoms arom_ats = allAts.get(lambda x, l = pep_aromList:\ x.parent.type+'_'+x.name in l) if not arom_ats: return AtomSet([]) for at in arom_ats: at.name = 'A' + at.name[1:] at.autodock_element = 'A' #print 'returning ', len(arom_ats), ' arom_ats' return arom_ats def getPeptideBondDict(self): resSet = self.chains.residues.get(lambda x, \ d = aromDict.keys():x.type in d) if not resSet: return BondSet() self.cyclecount = numres = len(resSet) #NB: cyclenum is 1 based because 0 means not numbered for i in range(numres): res = resSet[i] ats = res.atoms #bondDict keys are 1 based too keys = aromDict[res.type] bnds = bondDict[i+1] = ats.get(lambda x, \ keys=keys:x.name in keys).bonds[0] for b in bnds: bnds.cyclenum = i + 1 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 _numberCycle(self, at): for b in at.bonds: if hasattr(b,'incycle') and b.cyclenum==0 : b.cyclenum = self.cyclecount nxtAtom = b.atom1 if nxtAtom==at: nxtAtom = b.atom2 self._numberCycle(nxtAtom) def _getnxtAtom(self, at,b): nxtAtom = b.atom1 if nxtAtom==at: nxtAtom = b.atom2 return nxtAtom def _getAdjAtom(self,b,z): #first get the bonds in this cycle at = b.atom1 #next find the other one with at as one of the atoms: z2 = filter(lambda x,b=b,at=at,z=z:x!=b and x.atom1==at or x.atom2==at, z) #finally, return the other atom in this bond b.nextbond = z2[0] neighbor = self._getnxtAtom(at,z2[0]) b.next1 = neighbor def _getNormal(self,b): at1 = b.next1 at2 = b.atom1 at3 = b.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a = Numeric.subtract(pt2,pt1) b = Numeric.subtract(pt3,pt2) p = (a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]) nrmsize = Numeric.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]) return (nrmsize, p) def setroot(self, atom): """ setroot to 'C11' or 'hsg1:A:ILE2:CA' """ if type(atom)==types.StringType: if find(atom, ':')>-1: #have to use full_name list #check that it is an atom mols = ProteinSet([self]) nodes = mols.NodesFromName(atom) if not nodes: return 'invalid root name' if nodes.__class__!=AtomSet: return 'invalid root name: not atom level' else: nodes = self.allAtoms.get(lambda x, n = atom:x.name==n) if not nodes: return 'invalid root name' if len(nodes)>1: return 'root name must be unique' atom = nodes[0] elif type(atom)!=types.InstanceType: return atom, ' invalid root atom' elif atom.__class__!=Atom: return atom, ' can only select an Atom instance as root' #fix this rnum0 stuff #in case toggling back and forth if hasattr(self, 'autoRoot') and hasattr(self.autoRoot, 'rnum0'): delattr(self.autoRoot, 'rnum0') #if there is an old root, remove rnum0 if hasattr(self, 'ROOT') and hasattr(self.ROOT, 'rnum0'): delattr(self.ROOT, 'rnum0') self.ROOT = atom self.ROOT.rnum0 = 0 return self.ROOT def autoroot(self): """ autoRoot """ #clear old root if hasattr(self, 'ROOT') and hasattr(self.ROOT, 'rnum0'): delattr(self.ROOT, 'rnum0') if hasattr(self, 'autoRoot'): self.ROOT = self.autoRoot self.ROOT.rnum0 = 0 return if len(self.chains)>1: return "AutoRoot not implemented for molecules with >1 chain" self.bestBranch = len(self.allAtoms) bestList = [] for item in self.allAtoms: if not hasattr(item, 'bonds'): continue if len(item.bonds)==1 and item.bonds[0].leaf: continue if hasattr(item,'leaf'): continue item.maxbranch = 0 for b in item.bonds: nxtAtom = self._getnxtAtom(item,b) if not b.leaf: thistree = self.subTree(item,nxtAtom, self.allAtoms) thisbranch = len(thistree) if thisbranch>item.maxbranch: item.maxbranch = thisbranch #bestList holds all current best choices for Root.. if item.maxbranch<self.bestBranch: bestList = [] bestList.append(item) self.bestBranch = item.maxbranch if item.maxbranch==self.bestBranch and item not in bestList: bestList.append(item) if len(bestList)>1: foundCycle = 0 for at in bestList: at.cycleatom = 0 for b in at.bonds: #4/29: peptides won't have aromatic #but will have incycle #if b.bondOrder=='aromatic': if hasattr(b,'incycle'): at.cycleatom = 1 continue for at in bestList: if at.cycleatom: self.ROOT = at self.autoRoot = at self.ROOT.rnum0 =0 foundCycle = 1 break #if bestList had a cycle atom, it's been set to root..if NOT: if not foundCycle: self.autoRoot = bestList[0] self.ROOT = bestList[0] self.ROOT.rnum0 =0 #no ties for possible root, use bestRoot... else: self.autoRoot = bestList[0] self.ROOT = bestList[0] self.ROOT.rnum0 =0 return self.ROOT def buildTorsionTree(self): if not hasattr(self, 'ROOT'): print 'must set ROOT first!' return self.torTree = TorTree(self.parser, self.ROOT) def turnOnTorsion(self, bnd): """ turnOnTorsion """ if not bnd in self.rotatable: return #this is redundant (??) if not bnd.possibleTors: return if not bnd.activeTors: self.torscount = self.torscount + 1 bnd.activeTors = 1 self.torTree.addTorsion(bnd.atom1.number, bnd.atom2.number) def turnOffTorsion(self, bnd): """ turnOffTorsion """ if not bnd in self.rotatable: return #this is redundant (??) if not bnd.possibleTors: return if bnd.activeTors: self.torscount = self.torscount - 1 bnd.activeTors = 0 self.torTree.removeTorsion(bnd.atom1.number, bnd.atom2.number) def limitTorsions(self, numTors, type, simpleModel=1): """sets number of torsions to specified number by inactivating either those which move the fewest atoms or those which move the most. if number is > than current but less than possible, torsions are reactivated """ print 'lT: numTors=', numTors, ' type=', type allAts = self.allAtoms root = self.ROOT torscount = self.torscount print 'torscount=', torscount, #NB: torscount is not necessarily the max #ie it could have been adjusted already at0 = self.allAtoms[0] if not hasattr(self, 'torTree') or not hasattr(at0, 'tt_ind'): self.torTree = TorTree(self.parser, root) torsionMap = self.torTree.torsionMap torsionMapNum = len(torsionMap) print 'len(tm)=', torsionMapNum possibleTors = self.possible_torscount if simpleModel: self.setTorsions(numTors, type) return #FIX THIS: what if want to increase active torsions if torscount==numTors: msg = 'specified number==number present: no adjustment' return 'msg' elif torscount<numTors: if torscount==possibleTors: #if torscount==torsionMapNum: msg = 'specified number == number possible: no adjustment' return msg else: #in this case turn on as many as possible #if numTors>=torsionMapNum: if numTors>=possibleTors: #turn on everything delta = possibleTors - torscount #delta = torsionMapNum - torscount else: delta = numTors - torscount self.turnOnTorsions(delta, type) else: #torscount>numTors #in this case turn them off delta = torscount - numTors self.turnOffTorsions(delta, type) msg = str(delta) + ' torsions changed' return msg def setTorsions(self, numTors, type): #this assumes atoms have tt_ind field tNum = len(self.torTree.base_torsionMap) msg = "" if numTors>tNum: msg = 'too many torsions specified! '+ str(numTors)+ ' reducing to'+str(tNum) numTors = tNum if type=='fewest': rangeList = range(numTors) else: rangeList = [] for k in range(1, numTors+1): rangeList.append(-k) #turn them all off baseTorsionMap = self.torTree.base_torsionMap torsionMap = self.torTree.torsionMap #turn all active nodes off active_nodes = torsionMap[:] for node in active_nodes: #print 'turning off node ', node.number self.torTree.removeTorsion(node.bond[0], node.bond[1]) b = self.allAtoms.get(lambda x, node=node: x.tt_ind in node.bond).bonds[0][0] b.activeTors = 0 #turn on the right number at correct end for i in rangeList: node = baseTorsionMap[i] #print '2:turning on node ', node.number self.torTree.addTorsion(node.bond[0], node.bond[1]) b = self.allAtoms.get(lambda x, node=node: x.tt_ind in node.bond).bonds[0][0] b.activeTors = 1 #print 'now len(torsionMap)=', len(torsionMap) self.torscount = numTors return msg def turnOnTorsions(self, delta, type = 'fewest'): allAts = self.allAtoms torsionMap = self.torTree.torsionMap baseTorsionMap = self.torTree.base_torsionMap torscount = self.torscount #turn on delta torsions + adjust torscount in dict if type=='fewest': rangeList = range(delta) else: rangeList = [] for k in range(1, delta+1): rangeList.append(-k) #FIX THIS: probably doesn't work for i in rangeList: node = baseTorsionMap[i] b = allAts.get(lambda x, node=node: x.tt_ind in node.bond).bonds[0][0] if not b.activeTors: self.torTree.addTorsion(node.bond[0], node.bond[1]) b.activeTors = 1 else: lastInd = rangeList[-1] if type=='fewest': rangeList.append(lastInd+1) else: rangeList.append(lastInd-1) #torscount should be torscount + delta here self.torscount = torscount + delta def turnOffTorsions(self, delta, type = 'fewest'): allAts = self.allAtoms torsionMap = self.torTree.torsionMap baseTorsionMap = self.torTree.base_torsionMap torscount = self.torscount #turn on delta torsions + adjust torscount in dict if type=='fewest': rangeList = range(delta) else: rangeList = [] for k in range(1, delta+1): rangeList.append(-k) for i in rangeList: node = baseTorsionMap[i] if node.bond==(None,None): print 'error in turnOff torsions with ', rangeList break b = allAts.get(lambda x, node=node: x.tt_ind in node.bond).bonds[0][0] if b.activeTors: self.torTree.removeTorsion(node.bond[0], node.bond[1]) b.activeTors = 0 else: lastInd = rangeList[-1] if type=='fewest': rangeList.append(lastInd+1) else: rangeList.append(lastInd-1) self.torscount = torscount - delta def setCarbonName(self, at): """ setCarbonName """ if not at.element=='C': return if len(at.name)==1: at.name = 'C' else: at.name = 'C' + at.name[1:] def setAromaticName(self, at): """ setAromaticName """ if not at.element=='C': return if len(at.name)==1: at.name = 'A' else: at.name = 'A' + at.name[1:]
# NOTE each line has filename and list of indices # NOTE the first entry is the reference # NOTE THE NUMBER OF INDICES must match,indices must be comma-separated # (with NO intervening spaces) #read the data file fptr = open(data_filename) lines = fptr.readlines() fptr.close() #setup the reference molecule from MolKit import Read from MolKit.molecule import AtomSet ref_name, ref_ll = lines[0].split() ref_mol = Read(ref_name)[0] ref_ats = AtomSet() ref_indices = map(int, ref_ll.split(',')) num_ref_indices = len(ref_indices) if num_ref_indices<3: print " At least 3 indices are required! only %d indices found!!!"%(num_ref_indices) exit() for i in ref_indices: #ref_ats.append(ref_mol.allAtoms[i-1]) ref_ats.append(ref_mol.allAtoms.get(lambda x: x.number==i)[0]) num_ref_ats = len(ref_ats) #setup the tool for the rigid fit from mglutil.math.rigidFit import RigidfitBodyAligner RFA = RigidfitBodyAligner() RFA.setRefCoords(ref_ats.coords)
def nextFrame(self, id): #Player.nextFrame(self, id) id = int(id) if id == self.currentFrameIndex: return if self.hasCounter and self.gui: self.form.ent2.delete(0,'end') self.form.ent2.insert(0, str(id)) if self.hasSlider: self.form.ifd.entryByName['slider']['widget'].set(id) self.currentFrameIndex = int(id) removeAtoms = AtomSet([]) addAtoms = AtomSet([]) id = int(id) flood = self.floods[id] centers = [] materials = [] radii = [] prev_coords = self.mol.allAtoms.coords lenAtoms = len(prev_coords) #self.residue.atoms = AtomSet([]) index = 0 #h = self.hp.heap() #print h for fl in flood: x = (fl[1] - self.xcent)*self.spacing + self.centerx y = (fl[2] - self.ycent)*self.spacing + self.centery z = (fl[3] - self.zcent)*self.spacing + self.centerz if fl[4] == 7: atomchr = 'P' # note, this will color the NA atom pink (the PDB color for Phosphorus) radius = AAradii[13][0] if fl[4] == 6: atomchr = 'S' radius = AAradii[13][0] if fl[4] == 5: atomchr = 'A' radius = AAradii[10][0] if fl[4] == 4: atomchr = 'O' radius = AAradii[1][0] if fl[4] == 3: atomchr = 'N' radius = AAradii[4][0] if fl[4] == 2: atomchr = 'C' radius = AAradii[10][0] if fl[4] == 1: atomchr = 'H' radius = AAradii[15][0] if not [x,y,z] in prev_coords: a = Atom(atomchr, self.residue, atomchr, top=self.mol) a._coords = [[x,y,z]] a._charges = {} a.hetatm = 1 a.radius = radius #a.number = lenAtoms + 1 addAtoms.append(a) lenAtoms += 1 for key in self.colorKeys: a.colors[key]=AtomElements[atomchr] a.opacities[key]=1.0 else: centers.append([x,y,z]) # a = Atom(atomchr, self.residue, atomchr, top=self.mol) # a._coords = [[x,y,z]] # a._charges = {} # a.hetatm = 1 # a.number = index # index += 1 #aterials.append(AtomElements[atomchr]) #enters.append([x,y,z]) #adii.append(radius) #self.mol.allAtoms = self.residue.atoms #self.mol.geomContainer.geoms['lines'].protected = False #for com in self.autoLigandCommand.vf.cmdsWithOnAddObj: # com.onAddObjectToViewer(self.mol) #self.autoLigandCommand.vf.displayCPK(self.mol, scaleFactor=0.1) halo_centers = [] for coord in prev_coords: if not coord in centers: index = prev_coords.index(coord) removeAtoms.append(self.mol.allAtoms[index]) self.residue.assignUniqIndex() #this is needed to avoid Traceback later on self.mol.allAtoms.stringRepr = None #stringRepr can be very large aousing memory errors event = AddAtomsEvent(objects=addAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) event = DeleteAtomsEvent(objects=removeAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) for atom in removeAtoms: self.residue.atoms.remove(atom) if id == self.maxFrame: self.autoLigandCommand.halo.Set(visible=0) else: self.autoLigandCommand.halo.Set(centers=addAtoms.coords, materials=((1,1,0,0.5),), radii=0.4)
class AddBondsGUICommand(MVCommand, MVAtomICOM): """ The AddBondGUICommand provides an interactive way of creating bonds between two given atoms by picking on them. To use this command you need first to load it into PMV. Then you can find the entry 'addBonds' under the Edit menu. To add bonds you just need to pick on the 2 atoms you want to bind. If you drag select a bunch of atoms, the command will buildBondsByDistance between them.This command is undoable. \nPackage : Pmv \nModule : bondsCommands \nClass : AddBondsGUICommand \nCommand : addBondsGC \nSynopsis:\n None<-addBondsGC(atoms)\n \nRequired Arguments:\n atoms : atom(s)\n """ def __init__(self, func=None): MVCommand.__init__(self, func) MVAtomICOM.__init__(self) self.atomList = AtomSet([]) self.undoAtList = AtomSet([]) self.labelStrs = [] def onRemoveObjectFromViewer(self, obj): removeAts = AtomSet([]) for at in self.atomList: if at in obj.allAtoms: removeAts.append(at) self.atomList = self.atomList - removeAts removeAts = AtomSet([]) for at in self.undoAtList: if at in obj.allAtoms: removeAts.append(at) self.undoAtList = self.undoAtList - removeAts self.update() def onAddCmdToViewer(self): if not self.vf.commands.has_key('setICOM'): self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', topCommand=0) if not self.vf.commands.has_key('addBonds'): self.vf.loadCommand('bondsCommands', 'addBonds', 'Pmv', topCommand=0) if not self.vf.commands.has_key('removeBondsGC'): self.vf.loadCommand('bondsCommands', 'removeBondsGC', 'Pmv', topCommand=0) self.masterGeom = Geom('addBondsGeom',shape=(0,0), pickable=0, protected=True) self.masterGeom.isScalable = 0 self.spheres = Spheres(name='addBondsSpheres', shape=(0,3), inheritMaterial=0, radii=0.2, quality=15, materials = ((1.,1.,0.),), protected=True) if not self.vf.commands.has_key('labelByExpression'): self.vf.loadCommand('labelCommands', ['labelByExpression',], 'Pmv', topCommand=0) if self.vf.hasGui: miscGeom = self.vf.GUI.miscGeom self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=miscGeom) self.vf.GUI.VIEWER.AddObject(self.spheres, parent=self.masterGeom) def __call__(self, atoms, **kw): """None<-addBondsGC(atoms) \natoms : atom(s)""" if type(atoms) is StringType: self.nodeLogString = "'"+atoms+"'" ats = self.vf.expandNodes(atoms) if not len(ats): return 'ERROR' return apply(self.doitWrapper, (ats,), kw) def doit(self, ats): if len(ats)>2: if len(self.atomList): atSet = ats + self.atomList else: atSet = ats parent = atSet[0].parent parent.buildBondsByDistanceOnAtoms(atSet) self.atomList = AtomSet([]) self.update(True) else: lenAts = len(self.atomList) last = None if lenAts: last = self.atomList[-1] top = self.atomList[0].top for at in ats: #check for repeats of same atom if lenAts and at==last: continue #lenAts = len(self.atomList) #if lenAts and at==self.atomList[-1]: # continue if lenAts and at.top!=self.atomList[-1].top: msg = "intermolecular bond to %s disallowed"%(at.full_name()) self.warningMsg(msg) self.atomList.append(at) self.undoAtList.append(at) lenAts = len(self.atomList) self.update(True) #if only have one atom, there is nothing else to do if lenAts<2: return #now build bonds between pairs of atoms atSet = self.atomList if lenAts%2!=0: atSet = atSet[:-1] #all pairs of atoms will be bonded #so keep only the last one self.atomList = atSet[-1:] lenAts = lenAts -1 else: self.vf.labelByExpression(self.atomList, negate=1, topCommand=0) self.atomList = AtomSet([]) for i in range(0, lenAts, 2): at1 = atSet[i] at2 = atSet[i+1] self.vf.addBonds(at1, at2, origin='UserDefined', topCommand=0) self.update(True) def applyTransformation(self, pt, mat): pth = [pt[0], pt[1], pt[2], 1.0] return Numeric.dot(mat, pth)[:3] def getTransformedCoords(self, atom): if not atom.top.geomContainer: return atom.coords g = atom.top.geomContainer.geoms['master'] c = self.applyTransformation(atom.coords, g.GetMatrix(g)) return c.astype('f') def update(self, event=None): if not len(self.atomList): self.spheres.Set(vertices=[], tagModified=False) self.vf.labelByExpression(self.atomList, negate=1, topCommand=0) if self.vf.hasGui: self.vf.GUI.VIEWER.Redraw() return self.lineVertices=[] #each time have to recalculate lineVertices for at in self.atomList: c1 = self.getTransformedCoords(at) self.lineVertices.append(tuple(c1)) if event: self.spheres.Set(vertices=self.lineVertices, tagModified=False) self.vf.labelByExpression(self.atomList, function = 'lambda x: x.full_name()', lambdaFunc = 1, textcolor = 'yellow', format = '', negate = 0, location = 'Last', log = 0, font = 'arial1.glf', only = 1, topCommand=0) #setting spheres doesn't trigger redraw so do it explicitly if self.vf.hasGui: self.vf.GUI.VIEWER.Redraw() def guiCallback(self, event=None): self.save = self.vf.ICmdCaller.commands.value["Shift_L"] self.vf.setICOM(self, modifier="Shift_L", topCommand=0) def setupUndoAfter(self, ats, **kw): lenUndoAts = len(self.undoAtList) lenAts = len(ats) if lenAts==1: #after adding 1 self.atomList would be 1 or 0 if len(self.atomList)==1: s = '0' ustr='"c=self.addBondsGC; self.labelByExpression(c.atomList, negate=1, topCommand=0);c.atomList=c.atomList[:'+s+'];c.undoAtList=c.undoAtList[:-1];c.update()"' else: self.vf.undoCmdStack.remove(self.prev_undoCmds) ind = str(lenUndoAts - 2) ustr = '"c=self.addBondsGC;nodes=self.expandNodes('+'\''+self.undoAtList[-2:].full_name()+'\''+'); bonds=nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.atomList=nodes[:1];c.undoAtList=c.undoAtList[:'+ind+'];c.update()"' elif lenUndoAts>lenAts: ustr='"c=self.addBondsGC;nodes=self.expandNodes('+'\''+ats.full_name()+'\''+');bonds = nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.undoAtList=c.undoAtList[:'+str(lenAts)+']"' else: ustr='"c=self.addBondsGC;nodes=self.expandNodes('+'\''+ats.full_name()+'\''+');bonds = nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.undoAtList=c.undoAtList[:0]"' if len(self.atomList) and lenAts>1: atStr = self.atomList.full_name() estr = ';nodes=self.expandNodes('+'\''+self.atomList.full_name()+'\''+');c.atomList=nodes;c.update()"' ustr = ustr + estr self.undoCmds = "exec("+ustr+")" self.prev_undoCmds = (self.undoCmds, "addBondsGC") def startICOM(self): self.vf.setIcomLevel( Atom, topCommand=0) def stopICOM(self): if len(self.atomList)!=0: self.vf.labelByExpression(self.atomList, negate=1, topCommand = 0) del self.atomList[:] self.labelStrs = [] self.spheres.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() self.save = None
def getBondedAtoms(atom): l = AtomSet() for b in atom.bonds: l.append(b.neighborAtom(atom)) return l
def getDonors(self, nodes, paramDict): donorList = paramDict['donorTypes'] #print 'donorList=', donorList # currently this is a set of hydrogens hats = AtomSet(nodes.get(lambda x: x.element=='H')) #hats are optional: if none, process donors # if there are hats: dAts are all atoms bonded to all hydrogens if hats: dAts = AtomSet([]) for at in hats: for b in at.bonds: at2 = b.atom1 if id(at2)==id(at): at2 = b.atom2 dAts.append(at2) #dAts.append(b.neighborAtom(at)) else: dAts = nodes #get the sp2 hybridized possible donors which are all ns sp2 = [] for t in ['Nam', 'Ng+', 'Npl']: if t in donorList: sp2.append(t) #ntypes = ['Nam', 'Ng+', 'Npl'] sp2DAts = None if len(sp2): sp2DAts = AtomSet(dAts.get(lambda x, sp2=sp2: x.babel_type in sp2)) hsp2 = AtomSet([]) if sp2DAts: if hats: hsp2 = AtomSet(hats.get(lambda x, sp2DAts=sp2DAts:x.bonds[0].atom1 \ in sp2DAts or x.bonds[0].atom2 in sp2DAts)) if sp2DAts: #remove any sp2 N atoms which already have 3 bonds not to hydrogens n2Dons = AtomSet(sp2DAts.get(lambda x: x.element=='N')) if n2Dons: n2Dons.bl=0 for at in n2Dons: for b in at.bonds: if type(b.bondOrder)==type(2): at.bl = at.bl + b.bondOrder else: at.bl = at.bl + 2 #allow that there might already be a hydrogen nH = at.findHydrogens() at.bl = at.bl - len(nH) badAts = AtomSet(n2Dons.get(lambda x: x.bl>2)) if badAts: sp2DAts = sp2DAts - badAts delattr(n2Dons,'bl') #get the sp3 hybridized possible donors sp3 = [] for t in ['N3+', 'S3', 'O3']: if t in donorList: sp3.append(t) n3DAts = None if 'N3+' in sp3: n3DAts = AtomSet(dAts.get(lambda x: x.babel_type=='N3+')) o3DAts = None if 'O3' in sp3: o3DAts = AtomSet(dAts.get(lambda x: x.babel_type=='O3')) if o3DAts: #remove any O3 atoms which already have 2 bonds not to hydrogens badO3s = AtomSet([]) for at in o3DAts: if len(at.bonds)<2: continue if len(at.findHydrogens()): continue else: badO3s.append(at) if len(badO3s): o3DAts = o3DAts - badO3s s3DAts = None if 'S3' in sp3: s3DAts = AtomSet(dAts.get(lambda x: x.babel_type=='S3')) sp3DAts = AtomSet([]) for item in [n3DAts, o3DAts, s3DAts]: if item: sp3DAts = sp3DAts + item hsp3 = AtomSet([]) if sp3DAts: if hats: hsp3 = AtomSet(hats.get(lambda x, sp3DAts=sp3DAts:x.bonds[0].atom1 \ in sp3DAts or x.bonds[0].atom2 in sp3DAts)) hsp = hsp2 + hsp3 #print 'hsp=', hsp.name #print 'sp2DAts=', sp2DAts.name #print 'sp3DAts=', sp3DAts.name return hsp, sp2DAts, sp3DAts
mol.buildBondsByDistance() mol.LPO = AD4LigandPreparation(mol, mode='interactive', repairs='', charges_to_add=None, root=0, outputfilename=outputfilename, cleanup='') #rebuild torTree allAts = mol.allAtoms for b in allAts.bonds[0]: if b.activeTors: b.activeTors = 0 torscount = 0 tM = mol.torTree.torsionMap for i in range(len(tM)): bnum0, bnum1 = tM[i].bond a0 = allAts.get(lambda x: x.number==bnum0 + 1)[0] a0.tt_ind = bnum0 a1 = allAts.get(lambda x: x.number==bnum1 + 1)[0] a1.tt_ind = bnum1 b = AtomSet([a0,a1]).bonds[0] if hasattr(b, 'possibleTors'): assert b.possibleTors else: b.possibleTors = 1 b.activeTors = 1 torscount = torscount + 1 mol.torscount = torscount mol.ROOT = mol.allAtoms[0] mol.ROOT.rnum0 = 0 mol.LPO.write(outputfilename) # To execute this command type: # repair_ligand4.py -f pdbqt_filename [-o outputfilename] -v
def addHydrogens(self, mol): #check for bonds if len(mol.allAtoms.bonds[0])==0: mol.buildBondsByDistance() bonds = mol.allAtoms.bonds[0] #could have preset babel_types #so check if allAtoms are already typed try: t = mol.allAtoms.babel_type except: #if all are not pretyped, type them babel = AtomHybridization() babel.assignHybridization(mol.allAtoms) if self.method=='withBondOrder': mol.rings = RingFinder() mol.rings.findRings2(mol.allAtoms, mol.allAtoms.bonds[0]) mol.rings.bondRings = {} for ind in xrange(len(mol.rings.rings)): r = mol.rings.rings[ind] for b in r['bonds']: if not mol.rings.bondRings.has_key(b): mol.rings.bondRings[b] = [ind,] else: mol.rings.bondRings[b].append(ind) bo = BondOrder() bo.assignBondOrder(mol.allAtoms, bonds, mol.rings) mol.allAtoms._bndtyped = 1 # do aromatic here arom = Aromatic(mol.rings) arom.find_aromatic_atoms(mol.allAtoms) hat = AddHydrogens().addHydrogens(mol.allAtoms, method=self.method) bondedAtomDict = {} # key is heavy atom for a in hat: if bondedAtomDict.has_key(a[1]): bondedAtomDict[a[1]].append(a) else: bondedAtomDict[a[1]] = [a] # now create Atom object for hydrogens # and add the to the residues's atom list molNewHs = AtomSet([]) # list of created H atoms for this molecule heavyAtoms = AtomSet([]) # list of atoms that need new radii for heavyAtom, HatmsDscr in bondedAtomDict.items(): #don't add hydrogens to carbons: polar Only!!! if self.htype!='all' and heavyAtom.element=='C': continue res = heavyAtom.parent # find where to insert H atom childIndex = res.children.index(heavyAtom)+1 # loop over H atoms description to be added # start at the end to number correctly l = len(HatmsDscr) for i in range(l-1,-1,-1): a = HatmsDscr[i] # build H atom's name if len(heavyAtom.name)==1: name = 'H' + heavyAtom.name else: name = 'H' + heavyAtom.name[1:] # if more than 1 H atom, add H atom index # for instance HD11, HD12, Hd13 (index is 1,2,3) if l > 1: name = name + str(i+1) # create the H atom object atom = Atom(name, res, top=heavyAtom.top, chemicalElement='H', childIndex=childIndex, assignUniqIndex=0) # set atoms attributes atom._coords = [ a[0] ] if hasattr(a[1], 'segID'): atom.segID = a[1].segID atom.hetatm = 0 atom.alternate = [] #atom.element = 'H' atom.occupancy = 1.0 atom.conformation = 0 atom.temperatureFactor = 0.0 atom.babel_atomic_number = a[2] atom.babel_type = a[3] atom.babel_organic = 1 atom.radius = 1.2 # create the Bond object bonding Hatom to heavyAtom bond = Bond( a[1], atom, bondOrder=1) # add the created atom the the list molNewHs.append(atom) # in case this new hydrogen atom ever ends up in pmv # HAVE TO CREATE THESE ENTRIES # create the color entries for all geoemtries # available for the heavyAtom for key, value in heavyAtom.colors.items(): atom.colors[key]=(0.0, 1.0, 1.0) atom.opacities[key]=1.0 mol.allAtoms = mol.chains.residues.atoms if self.renumber: mol.allAtoms.number = range(1, len(mol.allAtoms)+1) return len(molNewHs)
def __init__(self, func=None): MVCommand.__init__(self, func) MVAtomICOM.__init__(self) self.atomList = AtomSet([]) self.undoAtList = AtomSet([]) self.labelStrs = []
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(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) 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(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 doit(self, ats): """ Function to delete all the references to each atom of a AtomSet.""" # Remove the atoms of the molecule you are deleting from the # the AtomSet self.vf.allAtoms self.vf.allAtoms = self.vf.allAtoms - ats # If the current selection atmsInSel = self.vf.selection.findType(Atom)[:] atmsInSel.sort() ats.sort() # Call the updateGeoms function for all the command having an # updateGeom function molecules, atomSets = self.vf.getNodesByMolecule(ats) done = 0 event = DeleteAtomsEvent(objects=ats) self.vf.dispatchEvent(event) allAtoms = AtomSet([]) for mol, atSet in map(None, molecules, atomSets): if len(atSet)==len(mol.allAtoms): #have to add atoms back to allAtoms for deleteMol to work self.vf.allAtoms = self.vf.allAtoms + atSet self.vf.deleteMol.deleteMol(mol) #if this is the last atom, quit the loop if mol==molecules[-1]: done=1 break continue mol.allAtoms = mol.allAtoms - atSet allAtoms = allAtoms + atSet #FIRST remove any possible hbonds hbondAts = atSet.get(lambda x: hasattr(x, 'hbonds')) if hbondAts is not None: #for each atom with hbonds for at in hbondAts: if not hasattr(at, 'hbonds'): continue #remove each of its hbonds for b in at.hbonds: self.removeHBond(b) for at in atSet: for b in at.bonds: at2 = b.atom1 if at2 == at: at2 = b.atom2 at2.bonds.remove(b) at.parent.remove(at, cleanup=1) if len(atmsInSel): if atmsInSel == ats: # the current selection was deleted self.vf.clearSelection(topCommand=0) else: nodes = self.vf.selection lenSel = len(nodes) setClass = nodes.__class__ elementClass = nodes.elementType if lenSel>0: # this breaks if selectionlevel is Molecule, for instance # setClass = nodes.__class__ # newSel = setClass(nodes.findType(Atom) - ats) # newSel2 = setClass([]) newSel = atmsInSel-ats newSel2 = AtomSet([]) # may have ats which have been deleted everywhere else for at in newSel: if at in at.top.allAtoms: newSel2.append(at) if len(newSel2)!=lenSel: self.vf.clearSelection(topCommand=0) if len(newSel2): newSel2 = newSel2.findType(elementClass).uniq() self.vf.select(newSel2, topCommand=0) #this fixed a bug which occurred when only 1 molecule present #and cmd invoked with mv.deleteAtomSet(mv.Mols[0].allAtoms) if not done: for at in ats: del at self.vf.resetUndo(topCommand=0)
def filterBasedOnAngs(self, pD, d2Ats, d3Ats, a2Ats, a3ats, paramDict): badAtDict = {} d2max = paramDict['d2max'] d2min = paramDict['d2min'] d3max = paramDict['d3max'] d3min = paramDict['d3min'] #NEED these parameters a2max = paramDict['a2max'] a2min = paramDict['a2min'] a3max = paramDict['a3max'] a3min = paramDict['a3min'] #NB now pD keys could be hydrogens OR donors for k in pD.keys(): if k.element=='H': d = k.bonds[0].atom1 if id(d)==id(k): d = k.bonds[0].atom2 #d = k.bonds[0].neighborAtom(k) h = k else: d = k h = None badAts = AtomSet([]) ct = 0 for ac in pD[k]: if h is not None: ang = getAngle(ac, h, d) else: acN = ac.bonds[0].atom1 if id(acN) == id(ac): acN = ac.bonds[0].atom2 #acN = ac.bonds[0].neighborAtom(ac) ang = getAngle(d, ac, acN) #print 'ang=', ang dSp2 = d in d2Ats aSp2 = ac in a2Ats #these limits could be adjustable if h is not None: if dSp2: upperLim = d2max lowerLim = d2min #upperLim = 170 #lowerLim = 130 else: upperLim = d3max lowerLim = d3min #upperLim = 180 #lowerLim = 120 else: #if there is no hydrogen use d-ac-acN angles if dSp2: upperLim = a2max lowerLim = a2min #upperLim = 150 #lowerLim = 110 else: upperLim = a3max lowerLim = a3min #upperLim = 150 #lowerLim = 100 if ang>lowerLim and ang <upperLim: #AT THIS MOMENT BUILD HYDROGEN BOND: if dSp2: if aSp2: typ = 22 else: typ = 23 elif aSp2: typ = 32 else: typ = 33 #THEY could be already bonded alreadyBonded = 0 if hasattr(d, 'hbonds') and hasattr(ac,'hbonds'): for hb in d.hbonds: if hb.donAt==ac or hb.accAt==ac: alreadyBonded = 1 if not alreadyBonded: newHB = HydrogenBond(d, ac, h, theta=ang, typ=typ) if not hasattr(ac, 'hbonds'): ac.hbonds=[] if not hasattr(d, 'hbonds'): d.hbonds=[] ac.hbonds.append(newHB) d.hbonds.append(newHB) if h is not None: #hydrogens can have only 1 hbond h.hbonds = [newHB] # newHB.hlen = dist #else: # newHB.dlen = dist else: badAts.append(ac) ct = ct + 1 badAtDict[k] = badAts return badAtDict