Example #1
0
 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()
Example #10
0
 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
Example #11
0
 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)
Example #12
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()
Example #13
0
 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
Example #14
0
    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))
Example #15
0
 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
Example #16
0
 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)
Example #17
0
    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
Example #18
0
 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), {})
Example #21
0
    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
Example #22
0
    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)
Example #23
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))
Example #25
0
    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)
Example #26
0
 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()
Example #27
0
 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)]
Example #28
0
 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')
Example #29
0
    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)
Example #30
0
    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)
Example #32
0
 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))
Example #33
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 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
Example #35
0
 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()
Example #36
0
    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
Example #37
0
 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()
Example #38
0
 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
Example #39
0
 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
Example #46
0
 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 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 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
Example #55
0
    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